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> 50*10725SJohn.Forte@Sun.COM #include <sys/pppt_ioctl.h> 517836SJohn.Forte@Sun.COM 527836SJohn.Forte@Sun.COM #define STMF_PATH "/devices/pseudo/stmf@0:admin" 539585STim.Szeto@Sun.COM #define SBD_PATH "/devices/pseudo/stmf_sbd@0:admin" 54*10725SJohn.Forte@Sun.COM #define PPPT_PATH "/devices/pseudo/pppt@0:pppt" 557836SJohn.Forte@Sun.COM 567836SJohn.Forte@Sun.COM #define EUI "eui." 577836SJohn.Forte@Sun.COM #define WWN "wwn." 587836SJohn.Forte@Sun.COM #define IQN "iqn." 599585STim.Szeto@Sun.COM #define LU_ASCII_GUID_SIZE 32 609585STim.Szeto@Sun.COM #define LU_GUID_SIZE 16 619585STim.Szeto@Sun.COM #define OUI_ASCII_SIZE 6 629585STim.Szeto@Sun.COM #define OUI_SIZE 3 637836SJohn.Forte@Sun.COM #define IDENT_LENGTH_BYTE 3 647836SJohn.Forte@Sun.COM 659585STim.Szeto@Sun.COM /* various initial allocation values */ 669585STim.Szeto@Sun.COM #define ALLOC_LU 8192 679585STim.Szeto@Sun.COM #define ALLOC_TARGET_PORT 2048 689585STim.Szeto@Sun.COM #define ALLOC_PROVIDER 64 699585STim.Szeto@Sun.COM #define ALLOC_GROUP 2048 709585STim.Szeto@Sun.COM #define ALLOC_SESSION 2048 719585STim.Szeto@Sun.COM #define ALLOC_VE 256 729585STim.Szeto@Sun.COM #define ALLOC_PP_DATA_SIZE 128*1024 739585STim.Szeto@Sun.COM #define ALLOC_GRP_MEMBER 256 749585STim.Szeto@Sun.COM 757836SJohn.Forte@Sun.COM #define MAX_ISCSI_NAME 223 769585STim.Szeto@Sun.COM #define MAX_SERIAL_SIZE 252 + 1 779585STim.Szeto@Sun.COM #define MAX_LU_ALIAS_SIZE 256 789585STim.Szeto@Sun.COM #define MAX_SBD_PROPS MAXPATHLEN + MAX_SERIAL_SIZE + MAX_LU_ALIAS_SIZE 797836SJohn.Forte@Sun.COM 807836SJohn.Forte@Sun.COM #define OPEN_STMF 0 817836SJohn.Forte@Sun.COM #define OPEN_EXCL_STMF O_EXCL 827836SJohn.Forte@Sun.COM 839585STim.Szeto@Sun.COM #define OPEN_SBD 0 849585STim.Szeto@Sun.COM #define OPEN_EXCL_SBD O_EXCL 859585STim.Szeto@Sun.COM 86*10725SJohn.Forte@Sun.COM #define OPEN_PPPT 0 87*10725SJohn.Forte@Sun.COM #define OPEN_EXCL_PPPT O_EXCL 88*10725SJohn.Forte@Sun.COM 897836SJohn.Forte@Sun.COM #define LOGICAL_UNIT_TYPE 0 907836SJohn.Forte@Sun.COM #define TARGET_TYPE 1 917836SJohn.Forte@Sun.COM #define STMF_SERVICE_TYPE 2 927836SJohn.Forte@Sun.COM 939585STim.Szeto@Sun.COM #define HOST_GROUP 1 949585STim.Szeto@Sun.COM #define TARGET_GROUP 2 959585STim.Szeto@Sun.COM 969585STim.Szeto@Sun.COM /* set default persistence here */ 979585STim.Szeto@Sun.COM #define STMF_DEFAULT_PERSIST STMF_PERSIST_SMF 989585STim.Szeto@Sun.COM 999585STim.Szeto@Sun.COM #define MAX_PROVIDER_RETRY 30 1009585STim.Szeto@Sun.COM 1017836SJohn.Forte@Sun.COM static int openStmf(int, int *fd); 1029585STim.Szeto@Sun.COM static int openSbd(int, int *fd); 103*10725SJohn.Forte@Sun.COM static int openPppt(int, int *fd); 1047836SJohn.Forte@Sun.COM static int groupIoctl(int fd, int cmd, stmfGroupName *); 1057836SJohn.Forte@Sun.COM static int loadStore(int fd); 1067836SJohn.Forte@Sun.COM static int initializeConfig(); 1077836SJohn.Forte@Sun.COM static int groupMemberIoctl(int fd, int cmd, stmfGroupName *, stmfDevid *); 1087836SJohn.Forte@Sun.COM static int guidCompare(const void *, const void *); 1097836SJohn.Forte@Sun.COM static int addViewEntryIoctl(int fd, stmfGuid *, stmfViewEntry *); 1107836SJohn.Forte@Sun.COM static int loadHostGroups(int fd, stmfGroupList *); 1117836SJohn.Forte@Sun.COM static int loadTargetGroups(int fd, stmfGroupList *); 1127836SJohn.Forte@Sun.COM static int getStmfState(stmf_state_desc_t *); 1137836SJohn.Forte@Sun.COM static int setStmfState(int fd, stmf_state_desc_t *, int); 1149585STim.Szeto@Sun.COM static int setProviderData(int fd, char *, nvlist_t *, int, uint64_t *); 1159585STim.Szeto@Sun.COM static int createDiskResource(luResourceImpl *); 1169585STim.Szeto@Sun.COM static int createDiskLu(diskResource *, stmfGuid *); 1179585STim.Szeto@Sun.COM static int deleteDiskLu(stmfGuid *luGuid); 1189585STim.Szeto@Sun.COM static int getDiskProp(luResourceImpl *, uint32_t, char *, size_t *); 1199585STim.Szeto@Sun.COM static int getDiskAllProps(stmfGuid *luGuid, luResource *hdl); 1209585STim.Szeto@Sun.COM static int loadDiskPropsFromDriver(luResourceImpl *, sbd_lu_props_t *); 1219585STim.Szeto@Sun.COM static int removeGuidFromDiskStore(stmfGuid *); 1229585STim.Szeto@Sun.COM static int addGuidToDiskStore(stmfGuid *, char *); 1239585STim.Szeto@Sun.COM static int persistDiskGuid(stmfGuid *, char *, boolean_t); 1249585STim.Szeto@Sun.COM static int setDiskProp(luResourceImpl *, uint32_t, const char *); 1259585STim.Szeto@Sun.COM static int checkHexUpper(char *); 1269585STim.Szeto@Sun.COM static int strToShift(const char *); 1279585STim.Szeto@Sun.COM static int niceStrToNum(const char *, uint64_t *); 1289585STim.Szeto@Sun.COM static void diskError(uint32_t, int *); 1299585STim.Szeto@Sun.COM static int importDiskLu(char *fname, stmfGuid *); 1309585STim.Szeto@Sun.COM static int modifyDiskLu(diskResource *, stmfGuid *, const char *); 1319585STim.Szeto@Sun.COM static int modifyDiskLuProp(stmfGuid *, const char *, uint32_t, const char *); 1329585STim.Szeto@Sun.COM static int validateModifyDiskProp(uint32_t); 1339585STim.Szeto@Sun.COM static uint8_t iGetPersistMethod(); 1349585STim.Szeto@Sun.COM static int groupListIoctl(stmfGroupList **, int); 1359585STim.Szeto@Sun.COM static int iLoadGroupFromPs(stmfGroupList **, int); 1369585STim.Szeto@Sun.COM static int groupMemberListIoctl(stmfGroupName *, stmfGroupProperties **, int); 1379585STim.Szeto@Sun.COM static int getProviderData(char *, nvlist_t **, int, uint64_t *); 138*10725SJohn.Forte@Sun.COM static int setDiskStandby(stmfGuid *luGuid); 1399585STim.Szeto@Sun.COM static int viewEntryCompare(const void *, const void *); 140*10725SJohn.Forte@Sun.COM static void deleteNonActiveLus(); 1419585STim.Szeto@Sun.COM 1429585STim.Szeto@Sun.COM static pthread_mutex_t persistenceTypeLock = PTHREAD_MUTEX_INITIALIZER; 1439585STim.Szeto@Sun.COM static int iPersistType = 0; 1449585STim.Szeto@Sun.COM /* when B_TRUE, no need to access SMF anymore. Just use iPersistType */ 1459585STim.Szeto@Sun.COM static boolean_t iLibSetPersist = B_FALSE; 1467836SJohn.Forte@Sun.COM 1477836SJohn.Forte@Sun.COM /* 1487836SJohn.Forte@Sun.COM * Open for stmf module 1497836SJohn.Forte@Sun.COM * 1507836SJohn.Forte@Sun.COM * flag - open flag (OPEN_STMF, OPEN_EXCL_STMF) 1517836SJohn.Forte@Sun.COM * fd - pointer to integer. On success, contains the stmf file descriptor 1527836SJohn.Forte@Sun.COM */ 1537836SJohn.Forte@Sun.COM static int 1547836SJohn.Forte@Sun.COM openStmf(int flag, int *fd) 1557836SJohn.Forte@Sun.COM { 1567836SJohn.Forte@Sun.COM int ret = STMF_STATUS_ERROR; 1577836SJohn.Forte@Sun.COM 1587836SJohn.Forte@Sun.COM if ((*fd = open(STMF_PATH, O_NDELAY | O_RDONLY | flag)) != -1) { 1597836SJohn.Forte@Sun.COM ret = STMF_STATUS_SUCCESS; 1607836SJohn.Forte@Sun.COM } else { 1617836SJohn.Forte@Sun.COM if (errno == EBUSY) { 1627836SJohn.Forte@Sun.COM ret = STMF_ERROR_BUSY; 1639585STim.Szeto@Sun.COM } else if (errno == EACCES) { 1649585STim.Szeto@Sun.COM ret = STMF_ERROR_PERM; 1657836SJohn.Forte@Sun.COM } else { 1667836SJohn.Forte@Sun.COM ret = STMF_STATUS_ERROR; 1677836SJohn.Forte@Sun.COM } 1687836SJohn.Forte@Sun.COM syslog(LOG_DEBUG, "openStmf:open failure:%s:errno(%d)", 1697836SJohn.Forte@Sun.COM STMF_PATH, errno); 1707836SJohn.Forte@Sun.COM } 1717836SJohn.Forte@Sun.COM 1727836SJohn.Forte@Sun.COM return (ret); 1737836SJohn.Forte@Sun.COM } 1747836SJohn.Forte@Sun.COM 1757836SJohn.Forte@Sun.COM /* 1769585STim.Szeto@Sun.COM * Open for sbd module 1779585STim.Szeto@Sun.COM * 178*10725SJohn.Forte@Sun.COM * flag - open flag (OPEN_SBD, OPEN_EXCL_SBD) 1799585STim.Szeto@Sun.COM * fd - pointer to integer. On success, contains the stmf file descriptor 1809585STim.Szeto@Sun.COM */ 1819585STim.Szeto@Sun.COM static int 1829585STim.Szeto@Sun.COM openSbd(int flag, int *fd) 1839585STim.Szeto@Sun.COM { 1849585STim.Szeto@Sun.COM int ret = STMF_STATUS_ERROR; 1859585STim.Szeto@Sun.COM 1869585STim.Szeto@Sun.COM if ((*fd = open(SBD_PATH, O_NDELAY | O_RDONLY | flag)) != -1) { 1879585STim.Szeto@Sun.COM ret = STMF_STATUS_SUCCESS; 1889585STim.Szeto@Sun.COM } else { 1899585STim.Szeto@Sun.COM if (errno == EBUSY) { 1909585STim.Szeto@Sun.COM ret = STMF_ERROR_BUSY; 1919585STim.Szeto@Sun.COM } else if (errno == EACCES) { 1929585STim.Szeto@Sun.COM ret = STMF_ERROR_PERM; 1939585STim.Szeto@Sun.COM } else { 1949585STim.Szeto@Sun.COM ret = STMF_STATUS_ERROR; 1959585STim.Szeto@Sun.COM } 1969585STim.Szeto@Sun.COM syslog(LOG_DEBUG, "openSbd:open failure:%s:errno(%d)", 1979585STim.Szeto@Sun.COM SBD_PATH, errno); 1989585STim.Szeto@Sun.COM } 1999585STim.Szeto@Sun.COM 2009585STim.Szeto@Sun.COM return (ret); 2019585STim.Szeto@Sun.COM } 2029585STim.Szeto@Sun.COM 2039585STim.Szeto@Sun.COM /* 204*10725SJohn.Forte@Sun.COM * Open for pppt module 205*10725SJohn.Forte@Sun.COM * 206*10725SJohn.Forte@Sun.COM * flag - open flag (OPEN_PPPT, OPEN_EXCL_PPPT) 207*10725SJohn.Forte@Sun.COM * fd - pointer to integer. On success, contains the stmf file descriptor 208*10725SJohn.Forte@Sun.COM */ 209*10725SJohn.Forte@Sun.COM static int 210*10725SJohn.Forte@Sun.COM openPppt(int flag, int *fd) 211*10725SJohn.Forte@Sun.COM { 212*10725SJohn.Forte@Sun.COM int ret = STMF_STATUS_ERROR; 213*10725SJohn.Forte@Sun.COM 214*10725SJohn.Forte@Sun.COM if ((*fd = open(PPPT_PATH, O_RDONLY | flag)) != -1) { 215*10725SJohn.Forte@Sun.COM ret = STMF_STATUS_SUCCESS; 216*10725SJohn.Forte@Sun.COM } else { 217*10725SJohn.Forte@Sun.COM if (errno == EBUSY) { 218*10725SJohn.Forte@Sun.COM ret = STMF_ERROR_BUSY; 219*10725SJohn.Forte@Sun.COM } else if (errno == EACCES) { 220*10725SJohn.Forte@Sun.COM ret = STMF_ERROR_PERM; 221*10725SJohn.Forte@Sun.COM } else { 222*10725SJohn.Forte@Sun.COM ret = STMF_STATUS_ERROR; 223*10725SJohn.Forte@Sun.COM } 224*10725SJohn.Forte@Sun.COM syslog(LOG_DEBUG, "openPppt:open failure:%s:errno(%d)", 225*10725SJohn.Forte@Sun.COM PPPT_PATH, errno); 226*10725SJohn.Forte@Sun.COM } 227*10725SJohn.Forte@Sun.COM 228*10725SJohn.Forte@Sun.COM return (ret); 229*10725SJohn.Forte@Sun.COM } 230*10725SJohn.Forte@Sun.COM 231*10725SJohn.Forte@Sun.COM /* 2327836SJohn.Forte@Sun.COM * initializeConfig 2337836SJohn.Forte@Sun.COM * 2347836SJohn.Forte@Sun.COM * This routine should be called before any ioctl requiring initialization 2357836SJohn.Forte@Sun.COM * which is basically everything except stmfGetState(), setStmfState() and 2367836SJohn.Forte@Sun.COM * stmfLoadConfig(). 2377836SJohn.Forte@Sun.COM */ 2387836SJohn.Forte@Sun.COM static int 2397836SJohn.Forte@Sun.COM initializeConfig() 2407836SJohn.Forte@Sun.COM { 2417836SJohn.Forte@Sun.COM int ret; 2427836SJohn.Forte@Sun.COM stmfState state; 2437836SJohn.Forte@Sun.COM 2447836SJohn.Forte@Sun.COM 2457836SJohn.Forte@Sun.COM ret = stmfGetState(&state); 2467836SJohn.Forte@Sun.COM if (ret != STMF_STATUS_SUCCESS) { 2477836SJohn.Forte@Sun.COM return (ret); 2487836SJohn.Forte@Sun.COM } 2497836SJohn.Forte@Sun.COM 2507836SJohn.Forte@Sun.COM /* if we've already initialized or in the process, return success */ 2517836SJohn.Forte@Sun.COM if (state.configState == STMF_CONFIG_STATE_INIT_DONE || 2527836SJohn.Forte@Sun.COM state.configState == STMF_CONFIG_STATE_INIT) { 2537836SJohn.Forte@Sun.COM return (STMF_STATUS_SUCCESS); 2547836SJohn.Forte@Sun.COM } 2557836SJohn.Forte@Sun.COM 2567836SJohn.Forte@Sun.COM ret = stmfLoadConfig(); 2577836SJohn.Forte@Sun.COM if (ret != STMF_STATUS_SUCCESS) { 2587836SJohn.Forte@Sun.COM syslog(LOG_DEBUG, 2597836SJohn.Forte@Sun.COM "initializeConfig:stmfLoadConfig:error(%d)", ret); 2607836SJohn.Forte@Sun.COM return (ret); 2617836SJohn.Forte@Sun.COM } 2627836SJohn.Forte@Sun.COM 2637836SJohn.Forte@Sun.COM ret = stmfGetState(&state); 2647836SJohn.Forte@Sun.COM if (ret != STMF_STATUS_SUCCESS) { 2657836SJohn.Forte@Sun.COM syslog(LOG_DEBUG, 2667836SJohn.Forte@Sun.COM "initializeConfig:stmfGetState:error(%d)", ret); 2677836SJohn.Forte@Sun.COM return (ret); 2687836SJohn.Forte@Sun.COM } 2697836SJohn.Forte@Sun.COM 2707836SJohn.Forte@Sun.COM if (state.configState != STMF_CONFIG_STATE_INIT_DONE) { 2717836SJohn.Forte@Sun.COM syslog(LOG_DEBUG, "initializeConfig:state.configState(%d)", 2727836SJohn.Forte@Sun.COM state.configState); 2737836SJohn.Forte@Sun.COM ret = STMF_STATUS_ERROR; 2747836SJohn.Forte@Sun.COM } 2757836SJohn.Forte@Sun.COM 2767836SJohn.Forte@Sun.COM return (ret); 2777836SJohn.Forte@Sun.COM } 2787836SJohn.Forte@Sun.COM 2797836SJohn.Forte@Sun.COM 2807836SJohn.Forte@Sun.COM /* 2817836SJohn.Forte@Sun.COM * groupIoctl 2827836SJohn.Forte@Sun.COM * 2837836SJohn.Forte@Sun.COM * Purpose: issue ioctl for create/delete on group 2847836SJohn.Forte@Sun.COM * 2857836SJohn.Forte@Sun.COM * cmd - valid STMF ioctl group cmd 2867836SJohn.Forte@Sun.COM * groupName - groupName to create or delete 2877836SJohn.Forte@Sun.COM */ 2887836SJohn.Forte@Sun.COM static int 2897836SJohn.Forte@Sun.COM groupIoctl(int fd, int cmd, stmfGroupName *groupName) 2907836SJohn.Forte@Sun.COM { 2917836SJohn.Forte@Sun.COM int ret = STMF_STATUS_SUCCESS; 2927836SJohn.Forte@Sun.COM int ioctlRet; 2937836SJohn.Forte@Sun.COM stmf_iocdata_t stmfIoctl; 2947836SJohn.Forte@Sun.COM stmf_group_name_t iGroupName; 2957836SJohn.Forte@Sun.COM 2967836SJohn.Forte@Sun.COM bzero(&iGroupName, sizeof (iGroupName)); 2977836SJohn.Forte@Sun.COM 2987836SJohn.Forte@Sun.COM bcopy(groupName, &iGroupName.name, strlen((char *)groupName)); 2997836SJohn.Forte@Sun.COM 3007836SJohn.Forte@Sun.COM iGroupName.name_size = strlen((char *)groupName); 3017836SJohn.Forte@Sun.COM 3027836SJohn.Forte@Sun.COM bzero(&stmfIoctl, sizeof (stmfIoctl)); 3037836SJohn.Forte@Sun.COM /* 3047836SJohn.Forte@Sun.COM * Issue ioctl to create the host group 3057836SJohn.Forte@Sun.COM */ 3067836SJohn.Forte@Sun.COM stmfIoctl.stmf_version = STMF_VERSION_1; 3077836SJohn.Forte@Sun.COM stmfIoctl.stmf_ibuf_size = sizeof (iGroupName); 3087836SJohn.Forte@Sun.COM stmfIoctl.stmf_ibuf = (uint64_t)(unsigned long)&iGroupName; 3097836SJohn.Forte@Sun.COM ioctlRet = ioctl(fd, cmd, &stmfIoctl); 3107836SJohn.Forte@Sun.COM if (ioctlRet != 0) { 3117836SJohn.Forte@Sun.COM switch (errno) { 3129585STim.Szeto@Sun.COM case EPERM: 3137836SJohn.Forte@Sun.COM case EACCES: 3147836SJohn.Forte@Sun.COM ret = STMF_ERROR_PERM; 3157836SJohn.Forte@Sun.COM break; 3167836SJohn.Forte@Sun.COM default: 3177836SJohn.Forte@Sun.COM switch (stmfIoctl.stmf_error) { 3187836SJohn.Forte@Sun.COM case STMF_IOCERR_TG_EXISTS: 3197836SJohn.Forte@Sun.COM case STMF_IOCERR_HG_EXISTS: 3207836SJohn.Forte@Sun.COM ret = STMF_ERROR_EXISTS; 3217836SJohn.Forte@Sun.COM break; 3227836SJohn.Forte@Sun.COM case STMF_IOCERR_TG_IN_USE: 3237836SJohn.Forte@Sun.COM case STMF_IOCERR_HG_IN_USE: 3247836SJohn.Forte@Sun.COM ret = STMF_ERROR_GROUP_IN_USE; 3257836SJohn.Forte@Sun.COM break; 3267836SJohn.Forte@Sun.COM case STMF_IOCERR_INVALID_HG: 3277836SJohn.Forte@Sun.COM case STMF_IOCERR_INVALID_TG: 3287836SJohn.Forte@Sun.COM ret = STMF_ERROR_NOT_FOUND; 3297836SJohn.Forte@Sun.COM break; 3307836SJohn.Forte@Sun.COM default: 3317836SJohn.Forte@Sun.COM syslog(LOG_DEBUG, 3327836SJohn.Forte@Sun.COM "groupIoctl:error(%d)", 3337836SJohn.Forte@Sun.COM stmfIoctl.stmf_error); 3347836SJohn.Forte@Sun.COM ret = STMF_STATUS_ERROR; 3357836SJohn.Forte@Sun.COM break; 3367836SJohn.Forte@Sun.COM } 3377836SJohn.Forte@Sun.COM break; 3387836SJohn.Forte@Sun.COM } 3397836SJohn.Forte@Sun.COM } 3407836SJohn.Forte@Sun.COM done: 3417836SJohn.Forte@Sun.COM return (ret); 3427836SJohn.Forte@Sun.COM } 3437836SJohn.Forte@Sun.COM 3447836SJohn.Forte@Sun.COM /* 3459585STim.Szeto@Sun.COM * groupMemberIoctl 3467836SJohn.Forte@Sun.COM * 3477836SJohn.Forte@Sun.COM * Purpose: issue ioctl for add/remove member on group 3487836SJohn.Forte@Sun.COM * 3497836SJohn.Forte@Sun.COM * cmd - valid STMF ioctl group member cmd 3507836SJohn.Forte@Sun.COM * groupName - groupName to add to or remove from 3517836SJohn.Forte@Sun.COM * devid - group member to add or remove 3527836SJohn.Forte@Sun.COM */ 3537836SJohn.Forte@Sun.COM static int 3547836SJohn.Forte@Sun.COM groupMemberIoctl(int fd, int cmd, stmfGroupName *groupName, stmfDevid *devid) 3557836SJohn.Forte@Sun.COM { 3567836SJohn.Forte@Sun.COM int ret = STMF_STATUS_SUCCESS; 3577836SJohn.Forte@Sun.COM int ioctlRet; 3587836SJohn.Forte@Sun.COM stmf_iocdata_t stmfIoctl; 3597836SJohn.Forte@Sun.COM stmf_group_op_data_t stmfGroupData; 3607836SJohn.Forte@Sun.COM 3617836SJohn.Forte@Sun.COM bzero(&stmfGroupData, sizeof (stmfGroupData)); 3627836SJohn.Forte@Sun.COM 3637836SJohn.Forte@Sun.COM bcopy(groupName, &stmfGroupData.group.name, strlen((char *)groupName)); 3647836SJohn.Forte@Sun.COM 3657836SJohn.Forte@Sun.COM stmfGroupData.group.name_size = strlen((char *)groupName); 3667836SJohn.Forte@Sun.COM stmfGroupData.ident[IDENT_LENGTH_BYTE] = devid->identLength; 3677836SJohn.Forte@Sun.COM bcopy(&(devid->ident), &stmfGroupData.ident[IDENT_LENGTH_BYTE + 1], 3687836SJohn.Forte@Sun.COM devid->identLength); 3697836SJohn.Forte@Sun.COM 3707836SJohn.Forte@Sun.COM bzero(&stmfIoctl, sizeof (stmfIoctl)); 3717836SJohn.Forte@Sun.COM /* 3727836SJohn.Forte@Sun.COM * Issue ioctl to add to the host group 3737836SJohn.Forte@Sun.COM */ 3747836SJohn.Forte@Sun.COM stmfIoctl.stmf_version = STMF_VERSION_1; 3757836SJohn.Forte@Sun.COM stmfIoctl.stmf_ibuf_size = sizeof (stmfGroupData); 3767836SJohn.Forte@Sun.COM stmfIoctl.stmf_ibuf = (uint64_t)(unsigned long)&stmfGroupData; 3777836SJohn.Forte@Sun.COM ioctlRet = ioctl(fd, cmd, &stmfIoctl); 3787836SJohn.Forte@Sun.COM if (ioctlRet != 0) { 3797836SJohn.Forte@Sun.COM switch (errno) { 3807836SJohn.Forte@Sun.COM case EBUSY: 3819884STim.Szeto@Sun.COM switch (stmfIoctl.stmf_error) { 3829884STim.Szeto@Sun.COM case STMF_IOCERR_TG_NEED_TG_OFFLINE: 3839884STim.Szeto@Sun.COM ret = STMF_ERROR_TG_ONLINE; 3849884STim.Szeto@Sun.COM break; 3859884STim.Szeto@Sun.COM default: 3869884STim.Szeto@Sun.COM ret = STMF_ERROR_BUSY; 3879884STim.Szeto@Sun.COM break; 3889884STim.Szeto@Sun.COM } 3897836SJohn.Forte@Sun.COM break; 3909585STim.Szeto@Sun.COM case EPERM: 3917836SJohn.Forte@Sun.COM case EACCES: 3927836SJohn.Forte@Sun.COM ret = STMF_ERROR_PERM; 3937836SJohn.Forte@Sun.COM break; 3947836SJohn.Forte@Sun.COM default: 3957836SJohn.Forte@Sun.COM switch (stmfIoctl.stmf_error) { 3967836SJohn.Forte@Sun.COM case STMF_IOCERR_TG_ENTRY_EXISTS: 3977836SJohn.Forte@Sun.COM case STMF_IOCERR_HG_ENTRY_EXISTS: 3987836SJohn.Forte@Sun.COM ret = STMF_ERROR_EXISTS; 3997836SJohn.Forte@Sun.COM break; 4007836SJohn.Forte@Sun.COM case STMF_IOCERR_INVALID_TG_ENTRY: 4017836SJohn.Forte@Sun.COM case STMF_IOCERR_INVALID_HG_ENTRY: 4027836SJohn.Forte@Sun.COM ret = 4037836SJohn.Forte@Sun.COM STMF_ERROR_MEMBER_NOT_FOUND; 4047836SJohn.Forte@Sun.COM break; 4057836SJohn.Forte@Sun.COM case STMF_IOCERR_INVALID_TG: 4067836SJohn.Forte@Sun.COM case STMF_IOCERR_INVALID_HG: 4077836SJohn.Forte@Sun.COM ret = 4087836SJohn.Forte@Sun.COM STMF_ERROR_GROUP_NOT_FOUND; 4097836SJohn.Forte@Sun.COM break; 4107836SJohn.Forte@Sun.COM default: 4117836SJohn.Forte@Sun.COM syslog(LOG_DEBUG, 4127836SJohn.Forte@Sun.COM "groupMemberIoctl:error" 4137836SJohn.Forte@Sun.COM "(%d)", 4147836SJohn.Forte@Sun.COM stmfIoctl.stmf_error); 4157836SJohn.Forte@Sun.COM ret = STMF_STATUS_ERROR; 4167836SJohn.Forte@Sun.COM break; 4177836SJohn.Forte@Sun.COM } 4187836SJohn.Forte@Sun.COM break; 4197836SJohn.Forte@Sun.COM } 4207836SJohn.Forte@Sun.COM } 4217836SJohn.Forte@Sun.COM done: 4227836SJohn.Forte@Sun.COM return (ret); 4237836SJohn.Forte@Sun.COM } 4247836SJohn.Forte@Sun.COM 4257836SJohn.Forte@Sun.COM /* 4269585STim.Szeto@Sun.COM * qsort function 4279585STim.Szeto@Sun.COM * sort on veIndex 4289585STim.Szeto@Sun.COM */ 4299585STim.Szeto@Sun.COM static int 4309585STim.Szeto@Sun.COM viewEntryCompare(const void *p1, const void *p2) 4319585STim.Szeto@Sun.COM { 4329585STim.Szeto@Sun.COM 4339585STim.Szeto@Sun.COM stmfViewEntry *v1 = (stmfViewEntry *)p1, *v2 = (stmfViewEntry *)p2; 4349585STim.Szeto@Sun.COM if (v1->veIndex > v2->veIndex) 4359585STim.Szeto@Sun.COM return (1); 4369585STim.Szeto@Sun.COM if (v1->veIndex < v2->veIndex) 4379585STim.Szeto@Sun.COM return (-1); 4389585STim.Szeto@Sun.COM return (0); 4399585STim.Szeto@Sun.COM } 4409585STim.Szeto@Sun.COM 4419585STim.Szeto@Sun.COM /* 4427836SJohn.Forte@Sun.COM * guidCompare 4437836SJohn.Forte@Sun.COM * 4447836SJohn.Forte@Sun.COM * qsort function 4457836SJohn.Forte@Sun.COM * sort on guid 4467836SJohn.Forte@Sun.COM */ 4477836SJohn.Forte@Sun.COM static int 4487836SJohn.Forte@Sun.COM guidCompare(const void *p1, const void *p2) 4497836SJohn.Forte@Sun.COM { 4507836SJohn.Forte@Sun.COM 4517836SJohn.Forte@Sun.COM stmfGuid *g1 = (stmfGuid *)p1, *g2 = (stmfGuid *)p2; 4527836SJohn.Forte@Sun.COM int i; 4537836SJohn.Forte@Sun.COM 4547836SJohn.Forte@Sun.COM for (i = 0; i < sizeof (stmfGuid); i++) { 4557836SJohn.Forte@Sun.COM if (g1->guid[i] > g2->guid[i]) 4567836SJohn.Forte@Sun.COM return (1); 4577836SJohn.Forte@Sun.COM if (g1->guid[i] < g2->guid[i]) 4587836SJohn.Forte@Sun.COM return (-1); 4597836SJohn.Forte@Sun.COM } 4607836SJohn.Forte@Sun.COM 4617836SJohn.Forte@Sun.COM return (0); 4627836SJohn.Forte@Sun.COM } 4637836SJohn.Forte@Sun.COM 4647836SJohn.Forte@Sun.COM /* 4657836SJohn.Forte@Sun.COM * stmfAddToHostGroup 4667836SJohn.Forte@Sun.COM * 4677836SJohn.Forte@Sun.COM * Purpose: Adds an initiator to an existing host group 4687836SJohn.Forte@Sun.COM * 4697836SJohn.Forte@Sun.COM * hostGroupName - name of an existing host group 4707836SJohn.Forte@Sun.COM * hostName - name of initiator to add 4717836SJohn.Forte@Sun.COM */ 4727836SJohn.Forte@Sun.COM int 4737836SJohn.Forte@Sun.COM stmfAddToHostGroup(stmfGroupName *hostGroupName, stmfDevid *hostName) 4747836SJohn.Forte@Sun.COM { 4757836SJohn.Forte@Sun.COM int ret; 4767836SJohn.Forte@Sun.COM int fd; 4777836SJohn.Forte@Sun.COM 4787836SJohn.Forte@Sun.COM if (hostGroupName == NULL || 4797836SJohn.Forte@Sun.COM (strnlen((char *)hostGroupName, sizeof (stmfGroupName)) 4807836SJohn.Forte@Sun.COM == sizeof (stmfGroupName)) || hostName == NULL) { 4817836SJohn.Forte@Sun.COM return (STMF_ERROR_INVALID_ARG); 4827836SJohn.Forte@Sun.COM } 4837836SJohn.Forte@Sun.COM 4847836SJohn.Forte@Sun.COM /* call init */ 4857836SJohn.Forte@Sun.COM ret = initializeConfig(); 4867836SJohn.Forte@Sun.COM if (ret != STMF_STATUS_SUCCESS) { 4877836SJohn.Forte@Sun.COM return (ret); 4887836SJohn.Forte@Sun.COM } 4897836SJohn.Forte@Sun.COM 4907836SJohn.Forte@Sun.COM /* 4917836SJohn.Forte@Sun.COM * Open control node for stmf 4927836SJohn.Forte@Sun.COM */ 4937836SJohn.Forte@Sun.COM if ((ret = openStmf(OPEN_STMF, &fd)) != STMF_STATUS_SUCCESS) 4947836SJohn.Forte@Sun.COM return (ret); 4957836SJohn.Forte@Sun.COM 4967836SJohn.Forte@Sun.COM if ((ret = groupMemberIoctl(fd, STMF_IOCTL_ADD_HG_ENTRY, hostGroupName, 4977836SJohn.Forte@Sun.COM hostName)) != STMF_STATUS_SUCCESS) { 4987836SJohn.Forte@Sun.COM goto done; 4997836SJohn.Forte@Sun.COM } 5007836SJohn.Forte@Sun.COM 5019585STim.Szeto@Sun.COM if (iGetPersistMethod() == STMF_PERSIST_NONE) { 5029585STim.Szeto@Sun.COM goto done; 5039585STim.Szeto@Sun.COM } 5049585STim.Szeto@Sun.COM 5057836SJohn.Forte@Sun.COM ret = psAddHostGroupMember((char *)hostGroupName, 5067836SJohn.Forte@Sun.COM (char *)hostName->ident); 5077836SJohn.Forte@Sun.COM switch (ret) { 5087836SJohn.Forte@Sun.COM case STMF_PS_SUCCESS: 5097836SJohn.Forte@Sun.COM ret = STMF_STATUS_SUCCESS; 5107836SJohn.Forte@Sun.COM break; 5117836SJohn.Forte@Sun.COM case STMF_PS_ERROR_EXISTS: 5127836SJohn.Forte@Sun.COM ret = STMF_ERROR_EXISTS; 5137836SJohn.Forte@Sun.COM break; 5147836SJohn.Forte@Sun.COM case STMF_PS_ERROR_GROUP_NOT_FOUND: 5157836SJohn.Forte@Sun.COM ret = STMF_ERROR_GROUP_NOT_FOUND; 5167836SJohn.Forte@Sun.COM break; 5177836SJohn.Forte@Sun.COM case STMF_PS_ERROR_BUSY: 5187836SJohn.Forte@Sun.COM ret = STMF_ERROR_BUSY; 5197836SJohn.Forte@Sun.COM break; 5207836SJohn.Forte@Sun.COM case STMF_PS_ERROR_SERVICE_NOT_FOUND: 5217836SJohn.Forte@Sun.COM ret = STMF_ERROR_SERVICE_NOT_FOUND; 5227836SJohn.Forte@Sun.COM break; 5237836SJohn.Forte@Sun.COM case STMF_PS_ERROR_VERSION_MISMATCH: 5247836SJohn.Forte@Sun.COM ret = STMF_ERROR_SERVICE_DATA_VERSION; 5257836SJohn.Forte@Sun.COM break; 5267836SJohn.Forte@Sun.COM default: 5277836SJohn.Forte@Sun.COM syslog(LOG_DEBUG, 5287836SJohn.Forte@Sun.COM "stmfAddToHostGroup:psAddHostGroupMember:error(%d)", 5297836SJohn.Forte@Sun.COM ret); 5307836SJohn.Forte@Sun.COM ret = STMF_STATUS_ERROR; 5317836SJohn.Forte@Sun.COM break; 5327836SJohn.Forte@Sun.COM } 5337836SJohn.Forte@Sun.COM 5347836SJohn.Forte@Sun.COM done: 5357836SJohn.Forte@Sun.COM (void) close(fd); 5367836SJohn.Forte@Sun.COM return (ret); 5377836SJohn.Forte@Sun.COM } 5387836SJohn.Forte@Sun.COM 5397836SJohn.Forte@Sun.COM /* 5407836SJohn.Forte@Sun.COM * stmfAddToTargetGroup 5417836SJohn.Forte@Sun.COM * 5427836SJohn.Forte@Sun.COM * Purpose: Adds a local port to an existing target group 5437836SJohn.Forte@Sun.COM * 5447836SJohn.Forte@Sun.COM * targetGroupName - name of an existing target group 5457836SJohn.Forte@Sun.COM * targetName - name of target to add 5467836SJohn.Forte@Sun.COM */ 5477836SJohn.Forte@Sun.COM int 5487836SJohn.Forte@Sun.COM stmfAddToTargetGroup(stmfGroupName *targetGroupName, stmfDevid *targetName) 5497836SJohn.Forte@Sun.COM { 5507836SJohn.Forte@Sun.COM int ret; 5517836SJohn.Forte@Sun.COM int fd; 5527836SJohn.Forte@Sun.COM 5537836SJohn.Forte@Sun.COM if (targetGroupName == NULL || 5547836SJohn.Forte@Sun.COM (strnlen((char *)targetGroupName, sizeof (stmfGroupName)) 5557836SJohn.Forte@Sun.COM == sizeof (stmfGroupName)) || targetName == NULL) { 5567836SJohn.Forte@Sun.COM return (STMF_ERROR_INVALID_ARG); 5577836SJohn.Forte@Sun.COM } 5587836SJohn.Forte@Sun.COM 5597836SJohn.Forte@Sun.COM /* call init */ 5607836SJohn.Forte@Sun.COM ret = initializeConfig(); 5617836SJohn.Forte@Sun.COM if (ret != STMF_STATUS_SUCCESS) { 5627836SJohn.Forte@Sun.COM return (ret); 5637836SJohn.Forte@Sun.COM } 5647836SJohn.Forte@Sun.COM 5657836SJohn.Forte@Sun.COM /* 5667836SJohn.Forte@Sun.COM * Open control node for stmf 5677836SJohn.Forte@Sun.COM */ 5687836SJohn.Forte@Sun.COM if ((ret = openStmf(OPEN_STMF, &fd)) != STMF_STATUS_SUCCESS) 5697836SJohn.Forte@Sun.COM return (ret); 5707836SJohn.Forte@Sun.COM 5717836SJohn.Forte@Sun.COM if ((ret = groupMemberIoctl(fd, STMF_IOCTL_ADD_TG_ENTRY, 5727836SJohn.Forte@Sun.COM targetGroupName, targetName)) != STMF_STATUS_SUCCESS) { 5737836SJohn.Forte@Sun.COM goto done; 5747836SJohn.Forte@Sun.COM } 5757836SJohn.Forte@Sun.COM 5769585STim.Szeto@Sun.COM if (iGetPersistMethod() == STMF_PERSIST_NONE) { 5779585STim.Szeto@Sun.COM goto done; 5789585STim.Szeto@Sun.COM } 5799585STim.Szeto@Sun.COM 5807836SJohn.Forte@Sun.COM ret = psAddTargetGroupMember((char *)targetGroupName, 5817836SJohn.Forte@Sun.COM (char *)targetName->ident); 5827836SJohn.Forte@Sun.COM switch (ret) { 5837836SJohn.Forte@Sun.COM case STMF_PS_SUCCESS: 5847836SJohn.Forte@Sun.COM ret = STMF_STATUS_SUCCESS; 5857836SJohn.Forte@Sun.COM break; 5867836SJohn.Forte@Sun.COM case STMF_PS_ERROR_EXISTS: 5877836SJohn.Forte@Sun.COM ret = STMF_ERROR_EXISTS; 5887836SJohn.Forte@Sun.COM break; 5897836SJohn.Forte@Sun.COM case STMF_PS_ERROR_GROUP_NOT_FOUND: 5907836SJohn.Forte@Sun.COM ret = STMF_ERROR_GROUP_NOT_FOUND; 5917836SJohn.Forte@Sun.COM break; 5927836SJohn.Forte@Sun.COM case STMF_PS_ERROR_BUSY: 5937836SJohn.Forte@Sun.COM ret = STMF_ERROR_BUSY; 5947836SJohn.Forte@Sun.COM break; 5957836SJohn.Forte@Sun.COM case STMF_PS_ERROR_SERVICE_NOT_FOUND: 5967836SJohn.Forte@Sun.COM ret = STMF_ERROR_SERVICE_NOT_FOUND; 5977836SJohn.Forte@Sun.COM break; 5987836SJohn.Forte@Sun.COM case STMF_PS_ERROR_VERSION_MISMATCH: 5997836SJohn.Forte@Sun.COM ret = STMF_ERROR_SERVICE_DATA_VERSION; 6007836SJohn.Forte@Sun.COM break; 6017836SJohn.Forte@Sun.COM default: 6027836SJohn.Forte@Sun.COM syslog(LOG_DEBUG, 6037836SJohn.Forte@Sun.COM "stmfAddToTargetGroup:psAddTargetGroupMember:" 6047836SJohn.Forte@Sun.COM "error(%d)", ret); 6057836SJohn.Forte@Sun.COM ret = STMF_STATUS_ERROR; 6067836SJohn.Forte@Sun.COM break; 6077836SJohn.Forte@Sun.COM } 6087836SJohn.Forte@Sun.COM 6097836SJohn.Forte@Sun.COM done: 6107836SJohn.Forte@Sun.COM (void) close(fd); 6117836SJohn.Forte@Sun.COM return (ret); 6127836SJohn.Forte@Sun.COM } 6137836SJohn.Forte@Sun.COM 6147836SJohn.Forte@Sun.COM /* 6157836SJohn.Forte@Sun.COM * addViewEntryIoctl 6167836SJohn.Forte@Sun.COM * 6177836SJohn.Forte@Sun.COM * Purpose: Issues ioctl to add a view entry 6187836SJohn.Forte@Sun.COM * 6197836SJohn.Forte@Sun.COM * lu - Logical Unit identifier to which the view entry is added 6207836SJohn.Forte@Sun.COM * viewEntry - view entry to add 6217836SJohn.Forte@Sun.COM * init - When set to B_TRUE, we are in the init state, i.e. don't call open 6227836SJohn.Forte@Sun.COM */ 6237836SJohn.Forte@Sun.COM static int 6247836SJohn.Forte@Sun.COM addViewEntryIoctl(int fd, stmfGuid *lu, stmfViewEntry *viewEntry) 6257836SJohn.Forte@Sun.COM { 6267836SJohn.Forte@Sun.COM int ret = STMF_STATUS_SUCCESS; 6277836SJohn.Forte@Sun.COM int ioctlRet; 6287836SJohn.Forte@Sun.COM stmf_iocdata_t stmfIoctl; 6297836SJohn.Forte@Sun.COM stmf_view_op_entry_t ioctlViewEntry; 6307836SJohn.Forte@Sun.COM 6317836SJohn.Forte@Sun.COM bzero(&ioctlViewEntry, sizeof (ioctlViewEntry)); 6327836SJohn.Forte@Sun.COM /* 6337836SJohn.Forte@Sun.COM * don't set ve_ndx or ve_ndx_valid as ve_ndx_valid should be 6347836SJohn.Forte@Sun.COM * false on input 6357836SJohn.Forte@Sun.COM */ 6367836SJohn.Forte@Sun.COM ioctlViewEntry.ve_lu_number_valid = viewEntry->luNbrValid; 6377836SJohn.Forte@Sun.COM ioctlViewEntry.ve_all_hosts = viewEntry->allHosts; 6387836SJohn.Forte@Sun.COM ioctlViewEntry.ve_all_targets = viewEntry->allTargets; 6397836SJohn.Forte@Sun.COM 6407836SJohn.Forte@Sun.COM if (viewEntry->allHosts == B_FALSE) { 6417836SJohn.Forte@Sun.COM bcopy(viewEntry->hostGroup, &ioctlViewEntry.ve_host_group.name, 6427836SJohn.Forte@Sun.COM sizeof (stmfGroupName)); 6437836SJohn.Forte@Sun.COM ioctlViewEntry.ve_host_group.name_size = 6447836SJohn.Forte@Sun.COM strlen((char *)viewEntry->hostGroup); 6457836SJohn.Forte@Sun.COM } 6467836SJohn.Forte@Sun.COM if (viewEntry->allTargets == B_FALSE) { 6477836SJohn.Forte@Sun.COM bcopy(viewEntry->targetGroup, 6487836SJohn.Forte@Sun.COM &ioctlViewEntry.ve_target_group.name, 6497836SJohn.Forte@Sun.COM sizeof (stmfGroupName)); 6507836SJohn.Forte@Sun.COM ioctlViewEntry.ve_target_group.name_size = 6517836SJohn.Forte@Sun.COM strlen((char *)viewEntry->targetGroup); 6527836SJohn.Forte@Sun.COM } 6537836SJohn.Forte@Sun.COM if (viewEntry->luNbrValid) { 6547836SJohn.Forte@Sun.COM bcopy(viewEntry->luNbr, &ioctlViewEntry.ve_lu_nbr, 6557836SJohn.Forte@Sun.COM sizeof (ioctlViewEntry.ve_lu_nbr)); 6567836SJohn.Forte@Sun.COM } 6577836SJohn.Forte@Sun.COM bcopy(lu, &ioctlViewEntry.ve_guid, sizeof (stmfGuid)); 6587836SJohn.Forte@Sun.COM 6597836SJohn.Forte@Sun.COM bzero(&stmfIoctl, sizeof (stmfIoctl)); 6607836SJohn.Forte@Sun.COM /* 6617836SJohn.Forte@Sun.COM * Issue ioctl to add to the view entry 6627836SJohn.Forte@Sun.COM */ 6637836SJohn.Forte@Sun.COM stmfIoctl.stmf_version = STMF_VERSION_1; 6647836SJohn.Forte@Sun.COM stmfIoctl.stmf_ibuf_size = sizeof (ioctlViewEntry); 6657836SJohn.Forte@Sun.COM stmfIoctl.stmf_ibuf = (uint64_t)(unsigned long)&ioctlViewEntry; 6667836SJohn.Forte@Sun.COM stmfIoctl.stmf_obuf_size = sizeof (ioctlViewEntry); 6677836SJohn.Forte@Sun.COM stmfIoctl.stmf_obuf = (uint64_t)(unsigned long)&ioctlViewEntry; 6687836SJohn.Forte@Sun.COM ioctlRet = ioctl(fd, STMF_IOCTL_ADD_VIEW_ENTRY, &stmfIoctl); 6697836SJohn.Forte@Sun.COM if (ioctlRet != 0) { 6707836SJohn.Forte@Sun.COM switch (errno) { 6717836SJohn.Forte@Sun.COM case EBUSY: 6727836SJohn.Forte@Sun.COM ret = STMF_ERROR_BUSY; 6737836SJohn.Forte@Sun.COM break; 6749585STim.Szeto@Sun.COM case EPERM: 6759585STim.Szeto@Sun.COM ret = STMF_ERROR_PERM; 6769585STim.Szeto@Sun.COM break; 6777836SJohn.Forte@Sun.COM case EACCES: 6787836SJohn.Forte@Sun.COM switch (stmfIoctl.stmf_error) { 6797836SJohn.Forte@Sun.COM case STMF_IOCERR_UPDATE_NEED_CFG_INIT: 6807836SJohn.Forte@Sun.COM ret = STMF_ERROR_CONFIG_NONE; 6817836SJohn.Forte@Sun.COM break; 6827836SJohn.Forte@Sun.COM default: 6837836SJohn.Forte@Sun.COM ret = STMF_ERROR_PERM; 6847836SJohn.Forte@Sun.COM break; 6857836SJohn.Forte@Sun.COM } 6867836SJohn.Forte@Sun.COM break; 6877836SJohn.Forte@Sun.COM default: 6887836SJohn.Forte@Sun.COM switch (stmfIoctl.stmf_error) { 6897836SJohn.Forte@Sun.COM case STMF_IOCERR_LU_NUMBER_IN_USE: 6907836SJohn.Forte@Sun.COM ret = STMF_ERROR_LUN_IN_USE; 6917836SJohn.Forte@Sun.COM break; 6927836SJohn.Forte@Sun.COM case STMF_IOCERR_VIEW_ENTRY_CONFLICT: 6937836SJohn.Forte@Sun.COM ret = STMF_ERROR_VE_CONFLICT; 6947836SJohn.Forte@Sun.COM break; 6957836SJohn.Forte@Sun.COM case STMF_IOCERR_UPDATE_NEED_CFG_INIT: 6967836SJohn.Forte@Sun.COM ret = STMF_ERROR_CONFIG_NONE; 6977836SJohn.Forte@Sun.COM break; 6987836SJohn.Forte@Sun.COM case STMF_IOCERR_INVALID_HG: 6997836SJohn.Forte@Sun.COM ret = STMF_ERROR_INVALID_HG; 7007836SJohn.Forte@Sun.COM break; 7017836SJohn.Forte@Sun.COM case STMF_IOCERR_INVALID_TG: 7027836SJohn.Forte@Sun.COM ret = STMF_ERROR_INVALID_TG; 7037836SJohn.Forte@Sun.COM break; 7047836SJohn.Forte@Sun.COM default: 7057836SJohn.Forte@Sun.COM syslog(LOG_DEBUG, 7067836SJohn.Forte@Sun.COM "addViewEntryIoctl" 7077836SJohn.Forte@Sun.COM ":error(%d)", 7087836SJohn.Forte@Sun.COM stmfIoctl.stmf_error); 7097836SJohn.Forte@Sun.COM ret = STMF_STATUS_ERROR; 7107836SJohn.Forte@Sun.COM break; 7117836SJohn.Forte@Sun.COM } 7127836SJohn.Forte@Sun.COM break; 7137836SJohn.Forte@Sun.COM } 7147836SJohn.Forte@Sun.COM goto done; 7157836SJohn.Forte@Sun.COM } 7167836SJohn.Forte@Sun.COM 7177836SJohn.Forte@Sun.COM /* copy lu nbr back to caller's view entry on success */ 7187836SJohn.Forte@Sun.COM viewEntry->veIndex = ioctlViewEntry.ve_ndx; 7197836SJohn.Forte@Sun.COM if (ioctlViewEntry.ve_lu_number_valid) { 7207836SJohn.Forte@Sun.COM bcopy(&ioctlViewEntry.ve_lu_nbr, viewEntry->luNbr, 7217836SJohn.Forte@Sun.COM sizeof (ioctlViewEntry.ve_lu_nbr)); 7227836SJohn.Forte@Sun.COM } 7237836SJohn.Forte@Sun.COM viewEntry->luNbrValid = B_TRUE; 7247836SJohn.Forte@Sun.COM 7257836SJohn.Forte@Sun.COM done: 7267836SJohn.Forte@Sun.COM return (ret); 7277836SJohn.Forte@Sun.COM } 7287836SJohn.Forte@Sun.COM 7297836SJohn.Forte@Sun.COM /* 7307836SJohn.Forte@Sun.COM * stmfAddViewEntry 7317836SJohn.Forte@Sun.COM * 7327836SJohn.Forte@Sun.COM * Purpose: Adds a view entry to a logical unit 7337836SJohn.Forte@Sun.COM * 7347836SJohn.Forte@Sun.COM * lu - guid of the logical unit to which the view entry is added 7357836SJohn.Forte@Sun.COM * viewEntry - view entry structure to add 7367836SJohn.Forte@Sun.COM */ 7377836SJohn.Forte@Sun.COM int 7387836SJohn.Forte@Sun.COM stmfAddViewEntry(stmfGuid *lu, stmfViewEntry *viewEntry) 7397836SJohn.Forte@Sun.COM { 7407836SJohn.Forte@Sun.COM int ret; 7417836SJohn.Forte@Sun.COM int fd; 7427836SJohn.Forte@Sun.COM stmfViewEntry iViewEntry; 7437836SJohn.Forte@Sun.COM 7447836SJohn.Forte@Sun.COM if (lu == NULL || viewEntry == NULL) { 7457836SJohn.Forte@Sun.COM return (STMF_ERROR_INVALID_ARG); 7467836SJohn.Forte@Sun.COM } 7477836SJohn.Forte@Sun.COM 7487836SJohn.Forte@Sun.COM /* initialize and set internal view entry */ 7497836SJohn.Forte@Sun.COM bzero(&iViewEntry, sizeof (iViewEntry)); 7507836SJohn.Forte@Sun.COM 7517836SJohn.Forte@Sun.COM if (!viewEntry->allHosts) { 7527836SJohn.Forte@Sun.COM bcopy(viewEntry->hostGroup, iViewEntry.hostGroup, 7537836SJohn.Forte@Sun.COM sizeof (iViewEntry.hostGroup)); 7547836SJohn.Forte@Sun.COM } else { 7557836SJohn.Forte@Sun.COM iViewEntry.allHosts = B_TRUE; 7567836SJohn.Forte@Sun.COM } 7577836SJohn.Forte@Sun.COM 7587836SJohn.Forte@Sun.COM if (!viewEntry->allTargets) { 7597836SJohn.Forte@Sun.COM bcopy(viewEntry->targetGroup, iViewEntry.targetGroup, 7607836SJohn.Forte@Sun.COM sizeof (iViewEntry.targetGroup)); 7617836SJohn.Forte@Sun.COM } else { 7627836SJohn.Forte@Sun.COM iViewEntry.allTargets = B_TRUE; 7637836SJohn.Forte@Sun.COM } 7647836SJohn.Forte@Sun.COM 7657836SJohn.Forte@Sun.COM if (viewEntry->luNbrValid) { 7667836SJohn.Forte@Sun.COM iViewEntry.luNbrValid = B_TRUE; 7677836SJohn.Forte@Sun.COM bcopy(viewEntry->luNbr, iViewEntry.luNbr, 7687836SJohn.Forte@Sun.COM sizeof (iViewEntry.luNbr)); 7697836SJohn.Forte@Sun.COM } 7707836SJohn.Forte@Sun.COM 7717836SJohn.Forte@Sun.COM /* 7727836SJohn.Forte@Sun.COM * set users return view entry index valid flag to false 7737836SJohn.Forte@Sun.COM * in case of failure 7747836SJohn.Forte@Sun.COM */ 7757836SJohn.Forte@Sun.COM viewEntry->veIndexValid = B_FALSE; 7767836SJohn.Forte@Sun.COM 7777836SJohn.Forte@Sun.COM /* Check to ensure service exists */ 7787836SJohn.Forte@Sun.COM if (psCheckService() != STMF_STATUS_SUCCESS) { 7797836SJohn.Forte@Sun.COM return (STMF_ERROR_SERVICE_NOT_FOUND); 7807836SJohn.Forte@Sun.COM } 7817836SJohn.Forte@Sun.COM 7827836SJohn.Forte@Sun.COM /* call init */ 7837836SJohn.Forte@Sun.COM ret = initializeConfig(); 7847836SJohn.Forte@Sun.COM if (ret != STMF_STATUS_SUCCESS) { 7857836SJohn.Forte@Sun.COM return (ret); 7867836SJohn.Forte@Sun.COM } 7877836SJohn.Forte@Sun.COM 7887836SJohn.Forte@Sun.COM /* 7897836SJohn.Forte@Sun.COM * Open control node for stmf 7907836SJohn.Forte@Sun.COM */ 7917836SJohn.Forte@Sun.COM if ((ret = openStmf(OPEN_STMF, &fd)) != STMF_STATUS_SUCCESS) 7927836SJohn.Forte@Sun.COM return (ret); 7937836SJohn.Forte@Sun.COM 7947836SJohn.Forte@Sun.COM /* 7957836SJohn.Forte@Sun.COM * First add the view entry to the driver 7967836SJohn.Forte@Sun.COM */ 7977836SJohn.Forte@Sun.COM ret = addViewEntryIoctl(fd, lu, &iViewEntry); 7987836SJohn.Forte@Sun.COM if (ret != STMF_STATUS_SUCCESS) { 7997836SJohn.Forte@Sun.COM goto done; 8007836SJohn.Forte@Sun.COM } 8017836SJohn.Forte@Sun.COM 8029585STim.Szeto@Sun.COM if (iGetPersistMethod() == STMF_PERSIST_NONE) { 8039585STim.Szeto@Sun.COM goto done; 8049585STim.Szeto@Sun.COM } 8059585STim.Szeto@Sun.COM 8067836SJohn.Forte@Sun.COM /* 8077836SJohn.Forte@Sun.COM * If the add to driver was successful, add it to the persistent 8087836SJohn.Forte@Sun.COM * store. 8097836SJohn.Forte@Sun.COM */ 8107836SJohn.Forte@Sun.COM ret = psAddViewEntry(lu, &iViewEntry); 8117836SJohn.Forte@Sun.COM switch (ret) { 8127836SJohn.Forte@Sun.COM case STMF_PS_SUCCESS: 8137836SJohn.Forte@Sun.COM ret = STMF_STATUS_SUCCESS; 8147836SJohn.Forte@Sun.COM break; 8157836SJohn.Forte@Sun.COM case STMF_PS_ERROR_NOT_FOUND: 8167836SJohn.Forte@Sun.COM ret = STMF_ERROR_NOT_FOUND; 8177836SJohn.Forte@Sun.COM break; 8187836SJohn.Forte@Sun.COM case STMF_PS_ERROR_BUSY: 8197836SJohn.Forte@Sun.COM ret = STMF_ERROR_BUSY; 8207836SJohn.Forte@Sun.COM break; 8217836SJohn.Forte@Sun.COM case STMF_PS_ERROR_SERVICE_NOT_FOUND: 8227836SJohn.Forte@Sun.COM ret = STMF_ERROR_SERVICE_NOT_FOUND; 8237836SJohn.Forte@Sun.COM break; 8247836SJohn.Forte@Sun.COM case STMF_PS_ERROR_VERSION_MISMATCH: 8257836SJohn.Forte@Sun.COM ret = STMF_ERROR_SERVICE_DATA_VERSION; 8267836SJohn.Forte@Sun.COM break; 8277836SJohn.Forte@Sun.COM default: 8287836SJohn.Forte@Sun.COM syslog(LOG_DEBUG, 8297836SJohn.Forte@Sun.COM "stmfAddViewEntry:psAddViewEntry:error(%d)", ret); 8307836SJohn.Forte@Sun.COM ret = STMF_STATUS_ERROR; 8317836SJohn.Forte@Sun.COM break; 8327836SJohn.Forte@Sun.COM } 8337836SJohn.Forte@Sun.COM 8347836SJohn.Forte@Sun.COM done: 8357836SJohn.Forte@Sun.COM (void) close(fd); 8367836SJohn.Forte@Sun.COM 8377836SJohn.Forte@Sun.COM if (ret == STMF_STATUS_SUCCESS) { 8387836SJohn.Forte@Sun.COM /* set caller's view entry on success */ 8397836SJohn.Forte@Sun.COM viewEntry->veIndexValid = iViewEntry.veIndexValid; 8407836SJohn.Forte@Sun.COM viewEntry->veIndex = iViewEntry.veIndex; 8417836SJohn.Forte@Sun.COM viewEntry->luNbrValid = B_TRUE; 8427836SJohn.Forte@Sun.COM bcopy(iViewEntry.luNbr, viewEntry->luNbr, 8437836SJohn.Forte@Sun.COM sizeof (iViewEntry.luNbr)); 8447836SJohn.Forte@Sun.COM } 8457836SJohn.Forte@Sun.COM return (ret); 8467836SJohn.Forte@Sun.COM } 8477836SJohn.Forte@Sun.COM 8487836SJohn.Forte@Sun.COM /* 8497836SJohn.Forte@Sun.COM * stmfClearProviderData 8507836SJohn.Forte@Sun.COM * 8517836SJohn.Forte@Sun.COM * Purpose: delete all provider data for specified provider 8527836SJohn.Forte@Sun.COM * 8537836SJohn.Forte@Sun.COM * providerName - name of provider for which data should be deleted 8547836SJohn.Forte@Sun.COM */ 8557836SJohn.Forte@Sun.COM int 8567836SJohn.Forte@Sun.COM stmfClearProviderData(char *providerName, int providerType) 8577836SJohn.Forte@Sun.COM { 8587836SJohn.Forte@Sun.COM int ret; 8597836SJohn.Forte@Sun.COM int fd; 8607836SJohn.Forte@Sun.COM int ioctlRet; 8617836SJohn.Forte@Sun.COM int savedErrno; 8627836SJohn.Forte@Sun.COM stmf_iocdata_t stmfIoctl; 8637836SJohn.Forte@Sun.COM stmf_ppioctl_data_t ppi; 8647836SJohn.Forte@Sun.COM 8657836SJohn.Forte@Sun.COM /* call init */ 8667836SJohn.Forte@Sun.COM ret = initializeConfig(); 8677836SJohn.Forte@Sun.COM if (ret != STMF_STATUS_SUCCESS) { 8687836SJohn.Forte@Sun.COM return (ret); 8697836SJohn.Forte@Sun.COM } 8707836SJohn.Forte@Sun.COM 8717836SJohn.Forte@Sun.COM if (providerName == NULL) { 8727836SJohn.Forte@Sun.COM return (STMF_ERROR_INVALID_ARG); 8737836SJohn.Forte@Sun.COM } 8747836SJohn.Forte@Sun.COM 8757836SJohn.Forte@Sun.COM if (providerType != STMF_LU_PROVIDER_TYPE && 8767836SJohn.Forte@Sun.COM providerType != STMF_PORT_PROVIDER_TYPE) { 8777836SJohn.Forte@Sun.COM return (STMF_ERROR_INVALID_ARG); 8787836SJohn.Forte@Sun.COM } 8797836SJohn.Forte@Sun.COM 8807836SJohn.Forte@Sun.COM /* 8817836SJohn.Forte@Sun.COM * Open control node for stmf 8827836SJohn.Forte@Sun.COM */ 8837836SJohn.Forte@Sun.COM if ((ret = openStmf(OPEN_STMF, &fd)) != STMF_STATUS_SUCCESS) 8847836SJohn.Forte@Sun.COM return (ret); 8857836SJohn.Forte@Sun.COM 8867836SJohn.Forte@Sun.COM bzero(&ppi, sizeof (ppi)); 8877836SJohn.Forte@Sun.COM 8887836SJohn.Forte@Sun.COM (void) strncpy(ppi.ppi_name, providerName, sizeof (ppi.ppi_name)); 8897836SJohn.Forte@Sun.COM 8907836SJohn.Forte@Sun.COM switch (providerType) { 8917836SJohn.Forte@Sun.COM case STMF_LU_PROVIDER_TYPE: 8927836SJohn.Forte@Sun.COM ppi.ppi_lu_provider = 1; 8937836SJohn.Forte@Sun.COM break; 8947836SJohn.Forte@Sun.COM case STMF_PORT_PROVIDER_TYPE: 8957836SJohn.Forte@Sun.COM ppi.ppi_port_provider = 1; 8967836SJohn.Forte@Sun.COM break; 8977836SJohn.Forte@Sun.COM default: 8987836SJohn.Forte@Sun.COM ret = STMF_ERROR_INVALID_ARG; 8997836SJohn.Forte@Sun.COM goto done; 9007836SJohn.Forte@Sun.COM } 9017836SJohn.Forte@Sun.COM 9027836SJohn.Forte@Sun.COM bzero(&stmfIoctl, sizeof (stmfIoctl)); 9037836SJohn.Forte@Sun.COM 9047836SJohn.Forte@Sun.COM stmfIoctl.stmf_version = STMF_VERSION_1; 9057836SJohn.Forte@Sun.COM stmfIoctl.stmf_ibuf_size = sizeof (stmf_ppioctl_data_t); 9067836SJohn.Forte@Sun.COM stmfIoctl.stmf_ibuf = (uint64_t)(unsigned long)&ppi; 9077836SJohn.Forte@Sun.COM 9087836SJohn.Forte@Sun.COM ioctlRet = ioctl(fd, STMF_IOCTL_CLEAR_PP_DATA, &stmfIoctl); 9097836SJohn.Forte@Sun.COM if (ioctlRet != 0) { 9107836SJohn.Forte@Sun.COM savedErrno = errno; 9117836SJohn.Forte@Sun.COM switch (savedErrno) { 9127836SJohn.Forte@Sun.COM case EBUSY: 9137836SJohn.Forte@Sun.COM ret = STMF_ERROR_BUSY; 9147836SJohn.Forte@Sun.COM break; 9159585STim.Szeto@Sun.COM case EPERM: 9167836SJohn.Forte@Sun.COM case EACCES: 9177836SJohn.Forte@Sun.COM ret = STMF_ERROR_PERM; 9187836SJohn.Forte@Sun.COM break; 9197836SJohn.Forte@Sun.COM default: 9207836SJohn.Forte@Sun.COM syslog(LOG_DEBUG, 9217836SJohn.Forte@Sun.COM "stmfClearProviderData:ioctl error(%d)", 9227836SJohn.Forte@Sun.COM ioctlRet); 9237836SJohn.Forte@Sun.COM ret = STMF_STATUS_ERROR; 9247836SJohn.Forte@Sun.COM break; 9257836SJohn.Forte@Sun.COM } 9267836SJohn.Forte@Sun.COM if (savedErrno != ENOENT) { 9277836SJohn.Forte@Sun.COM goto done; 9287836SJohn.Forte@Sun.COM } 9297836SJohn.Forte@Sun.COM } 9307836SJohn.Forte@Sun.COM 9319585STim.Szeto@Sun.COM if (iGetPersistMethod() == STMF_PERSIST_NONE) { 9329585STim.Szeto@Sun.COM goto done; 9339585STim.Szeto@Sun.COM } 9349585STim.Szeto@Sun.COM 9357836SJohn.Forte@Sun.COM ret = psClearProviderData(providerName, providerType); 9367836SJohn.Forte@Sun.COM switch (ret) { 9377836SJohn.Forte@Sun.COM case STMF_PS_SUCCESS: 9387836SJohn.Forte@Sun.COM ret = STMF_STATUS_SUCCESS; 9397836SJohn.Forte@Sun.COM break; 9407836SJohn.Forte@Sun.COM case STMF_PS_ERROR_NOT_FOUND: 9417836SJohn.Forte@Sun.COM ret = STMF_ERROR_NOT_FOUND; 9427836SJohn.Forte@Sun.COM break; 9437836SJohn.Forte@Sun.COM case STMF_PS_ERROR_BUSY: 9447836SJohn.Forte@Sun.COM ret = STMF_ERROR_BUSY; 9457836SJohn.Forte@Sun.COM break; 9467836SJohn.Forte@Sun.COM case STMF_PS_ERROR_SERVICE_NOT_FOUND: 9477836SJohn.Forte@Sun.COM ret = STMF_ERROR_SERVICE_NOT_FOUND; 9487836SJohn.Forte@Sun.COM break; 9497836SJohn.Forte@Sun.COM case STMF_PS_ERROR_VERSION_MISMATCH: 9507836SJohn.Forte@Sun.COM ret = STMF_ERROR_SERVICE_DATA_VERSION; 9517836SJohn.Forte@Sun.COM break; 9527836SJohn.Forte@Sun.COM default: 9537836SJohn.Forte@Sun.COM syslog(LOG_DEBUG, 9547836SJohn.Forte@Sun.COM "stmfClearProviderData:psClearProviderData" 9557836SJohn.Forte@Sun.COM ":error(%d)", ret); 9567836SJohn.Forte@Sun.COM ret = STMF_STATUS_ERROR; 9577836SJohn.Forte@Sun.COM break; 9587836SJohn.Forte@Sun.COM } 9597836SJohn.Forte@Sun.COM 9607836SJohn.Forte@Sun.COM done: 9617836SJohn.Forte@Sun.COM (void) close(fd); 9627836SJohn.Forte@Sun.COM return (ret); 9637836SJohn.Forte@Sun.COM } 9647836SJohn.Forte@Sun.COM 9657836SJohn.Forte@Sun.COM /* 9667836SJohn.Forte@Sun.COM * stmfCreateHostGroup 9677836SJohn.Forte@Sun.COM * 9687836SJohn.Forte@Sun.COM * Purpose: Create a new initiator group 9697836SJohn.Forte@Sun.COM * 9707836SJohn.Forte@Sun.COM * hostGroupName - name of host group to create 9717836SJohn.Forte@Sun.COM */ 9727836SJohn.Forte@Sun.COM int 9737836SJohn.Forte@Sun.COM stmfCreateHostGroup(stmfGroupName *hostGroupName) 9747836SJohn.Forte@Sun.COM { 9757836SJohn.Forte@Sun.COM int ret; 9767836SJohn.Forte@Sun.COM int fd; 9777836SJohn.Forte@Sun.COM 9787836SJohn.Forte@Sun.COM if (hostGroupName == NULL || 9797836SJohn.Forte@Sun.COM (strnlen((char *)hostGroupName, sizeof (stmfGroupName)) 9807836SJohn.Forte@Sun.COM == sizeof (stmfGroupName))) { 9817836SJohn.Forte@Sun.COM return (STMF_ERROR_INVALID_ARG); 9827836SJohn.Forte@Sun.COM } 9837836SJohn.Forte@Sun.COM 9847836SJohn.Forte@Sun.COM /* Check to ensure service exists */ 9857836SJohn.Forte@Sun.COM if (psCheckService() != STMF_STATUS_SUCCESS) { 9867836SJohn.Forte@Sun.COM return (STMF_ERROR_SERVICE_NOT_FOUND); 9877836SJohn.Forte@Sun.COM } 9887836SJohn.Forte@Sun.COM 9897836SJohn.Forte@Sun.COM /* call init */ 9907836SJohn.Forte@Sun.COM ret = initializeConfig(); 9917836SJohn.Forte@Sun.COM if (ret != STMF_STATUS_SUCCESS) { 9927836SJohn.Forte@Sun.COM return (ret); 9937836SJohn.Forte@Sun.COM } 9947836SJohn.Forte@Sun.COM 9957836SJohn.Forte@Sun.COM /* 9967836SJohn.Forte@Sun.COM * Open control node for stmf 9977836SJohn.Forte@Sun.COM */ 9987836SJohn.Forte@Sun.COM if ((ret = openStmf(OPEN_STMF, &fd)) != STMF_STATUS_SUCCESS) 9997836SJohn.Forte@Sun.COM return (ret); 10007836SJohn.Forte@Sun.COM 10017836SJohn.Forte@Sun.COM if ((ret = groupIoctl(fd, STMF_IOCTL_CREATE_HOST_GROUP, 10027836SJohn.Forte@Sun.COM hostGroupName)) != STMF_STATUS_SUCCESS) { 10037836SJohn.Forte@Sun.COM goto done; 10047836SJohn.Forte@Sun.COM } 10057836SJohn.Forte@Sun.COM 10069585STim.Szeto@Sun.COM if (iGetPersistMethod() == STMF_PERSIST_NONE) { 10079585STim.Szeto@Sun.COM goto done; 10089585STim.Szeto@Sun.COM } 10099585STim.Szeto@Sun.COM 10107836SJohn.Forte@Sun.COM ret = psCreateHostGroup((char *)hostGroupName); 10117836SJohn.Forte@Sun.COM switch (ret) { 10127836SJohn.Forte@Sun.COM case STMF_PS_SUCCESS: 10137836SJohn.Forte@Sun.COM ret = STMF_STATUS_SUCCESS; 10147836SJohn.Forte@Sun.COM break; 10157836SJohn.Forte@Sun.COM case STMF_PS_ERROR_EXISTS: 10167836SJohn.Forte@Sun.COM ret = STMF_ERROR_EXISTS; 10177836SJohn.Forte@Sun.COM break; 10187836SJohn.Forte@Sun.COM case STMF_PS_ERROR_BUSY: 10197836SJohn.Forte@Sun.COM ret = STMF_ERROR_BUSY; 10207836SJohn.Forte@Sun.COM break; 10217836SJohn.Forte@Sun.COM case STMF_PS_ERROR_SERVICE_NOT_FOUND: 10227836SJohn.Forte@Sun.COM ret = STMF_ERROR_SERVICE_NOT_FOUND; 10237836SJohn.Forte@Sun.COM break; 10247836SJohn.Forte@Sun.COM case STMF_PS_ERROR_VERSION_MISMATCH: 10257836SJohn.Forte@Sun.COM ret = STMF_ERROR_SERVICE_DATA_VERSION; 10267836SJohn.Forte@Sun.COM break; 10277836SJohn.Forte@Sun.COM default: 10287836SJohn.Forte@Sun.COM syslog(LOG_DEBUG, 10297836SJohn.Forte@Sun.COM "stmfCreateHostGroup:psCreateHostGroup:error(%d)", 10307836SJohn.Forte@Sun.COM ret); 10317836SJohn.Forte@Sun.COM ret = STMF_STATUS_ERROR; 10327836SJohn.Forte@Sun.COM break; 10337836SJohn.Forte@Sun.COM } 10347836SJohn.Forte@Sun.COM 10357836SJohn.Forte@Sun.COM done: 10367836SJohn.Forte@Sun.COM (void) close(fd); 10377836SJohn.Forte@Sun.COM return (ret); 10387836SJohn.Forte@Sun.COM } 10397836SJohn.Forte@Sun.COM 10407836SJohn.Forte@Sun.COM /* 10419585STim.Szeto@Sun.COM * stmfCreateLu 10429585STim.Szeto@Sun.COM * 10439585STim.Szeto@Sun.COM * Purpose: Create a logical unit 10449585STim.Szeto@Sun.COM * 10459585STim.Szeto@Sun.COM * hdl - handle to logical unit resource created via stmfCreateLuResource 10469585STim.Szeto@Sun.COM * 10479585STim.Szeto@Sun.COM * luGuid - If non-NULL, on success, contains the guid of the created logical 10489585STim.Szeto@Sun.COM * unit 10499585STim.Szeto@Sun.COM */ 10509585STim.Szeto@Sun.COM int 10519585STim.Szeto@Sun.COM stmfCreateLu(luResource hdl, stmfGuid *luGuid) 10529585STim.Szeto@Sun.COM { 10539585STim.Szeto@Sun.COM int ret = STMF_STATUS_SUCCESS; 10549585STim.Szeto@Sun.COM luResourceImpl *luPropsHdl = hdl; 10559585STim.Szeto@Sun.COM 10569585STim.Szeto@Sun.COM if (hdl == NULL) { 10579585STim.Szeto@Sun.COM return (STMF_ERROR_INVALID_ARG); 10589585STim.Szeto@Sun.COM } 10599585STim.Szeto@Sun.COM 10609585STim.Szeto@Sun.COM if (luPropsHdl->type == STMF_DISK) { 10619585STim.Szeto@Sun.COM ret = createDiskLu((diskResource *)luPropsHdl->resource, 10629585STim.Szeto@Sun.COM luGuid); 10639585STim.Szeto@Sun.COM } else { 10649585STim.Szeto@Sun.COM return (STMF_ERROR_INVALID_ARG); 10659585STim.Szeto@Sun.COM } 10669585STim.Szeto@Sun.COM 10679585STim.Szeto@Sun.COM return (ret); 10689585STim.Szeto@Sun.COM } 10699585STim.Szeto@Sun.COM 10709585STim.Szeto@Sun.COM /* 10719585STim.Szeto@Sun.COM * stmfCreateLuResource 10729585STim.Szeto@Sun.COM * 10739585STim.Szeto@Sun.COM * Purpose: Create resource handle for a logical unit 10749585STim.Szeto@Sun.COM * 10759585STim.Szeto@Sun.COM * dType - Type of logical unit resource to create 10769585STim.Szeto@Sun.COM * Can be: STMF_DISK 10779585STim.Szeto@Sun.COM * 10789585STim.Szeto@Sun.COM * hdl - pointer to luResource 10799585STim.Szeto@Sun.COM */ 10809585STim.Szeto@Sun.COM int 10819585STim.Szeto@Sun.COM stmfCreateLuResource(uint16_t dType, luResource *hdl) 10829585STim.Szeto@Sun.COM { 10839585STim.Szeto@Sun.COM int ret = STMF_STATUS_SUCCESS; 10849585STim.Szeto@Sun.COM 10859585STim.Szeto@Sun.COM if (dType != STMF_DISK || hdl == NULL) { 10869585STim.Szeto@Sun.COM return (STMF_ERROR_INVALID_ARG); 10879585STim.Szeto@Sun.COM } 10889585STim.Szeto@Sun.COM 10899585STim.Szeto@Sun.COM *hdl = calloc(1, sizeof (luResourceImpl)); 10909585STim.Szeto@Sun.COM if (*hdl == NULL) { 10919585STim.Szeto@Sun.COM return (STMF_ERROR_NOMEM); 10929585STim.Szeto@Sun.COM } 10939585STim.Szeto@Sun.COM 10949585STim.Szeto@Sun.COM ret = createDiskResource((luResourceImpl *)*hdl); 10959585STim.Szeto@Sun.COM if (ret != STMF_STATUS_SUCCESS) { 10969585STim.Szeto@Sun.COM free(*hdl); 10979585STim.Szeto@Sun.COM return (ret); 10989585STim.Szeto@Sun.COM } 10999585STim.Szeto@Sun.COM 11009585STim.Szeto@Sun.COM return (STMF_STATUS_SUCCESS); 11019585STim.Szeto@Sun.COM } 11029585STim.Szeto@Sun.COM 11039585STim.Szeto@Sun.COM /* 11049585STim.Szeto@Sun.COM * Creates a disk logical unit 11059585STim.Szeto@Sun.COM * 11069585STim.Szeto@Sun.COM * disk - pointer to diskResource structure that represents the properties 11079585STim.Szeto@Sun.COM * for the disk logical unit to be created. 11089585STim.Szeto@Sun.COM */ 11099585STim.Szeto@Sun.COM static int 11109585STim.Szeto@Sun.COM createDiskLu(diskResource *disk, stmfGuid *createdGuid) 11119585STim.Szeto@Sun.COM { 11129585STim.Szeto@Sun.COM int ret = STMF_STATUS_SUCCESS; 11139585STim.Szeto@Sun.COM int dataFileNameLen = 0; 11149585STim.Szeto@Sun.COM int metaFileNameLen = 0; 11159585STim.Szeto@Sun.COM int serialNumLen = 0; 11169585STim.Szeto@Sun.COM int luAliasLen = 0; 111710113SNattuvetty.Bhavyan@Sun.COM int luMgmtUrlLen = 0; 11189585STim.Szeto@Sun.COM int sluBufSize = 0; 11199585STim.Szeto@Sun.COM int bufOffset = 0; 11209585STim.Szeto@Sun.COM int fd = 0; 11219585STim.Szeto@Sun.COM int ioctlRet; 11229585STim.Szeto@Sun.COM int savedErrno; 11239585STim.Szeto@Sun.COM stmfGuid guid; 11249585STim.Szeto@Sun.COM stmf_iocdata_t sbdIoctl = {0}; 11259585STim.Szeto@Sun.COM 11269585STim.Szeto@Sun.COM sbd_create_and_reg_lu_t *sbdLu = NULL; 11279585STim.Szeto@Sun.COM 11289585STim.Szeto@Sun.COM /* 11299585STim.Szeto@Sun.COM * Open control node for sbd 11309585STim.Szeto@Sun.COM */ 11319585STim.Szeto@Sun.COM if ((ret = openSbd(OPEN_SBD, &fd)) != STMF_STATUS_SUCCESS) 11329585STim.Szeto@Sun.COM return (ret); 11339585STim.Szeto@Sun.COM 11349585STim.Szeto@Sun.COM /* data file name must be specified */ 11359585STim.Szeto@Sun.COM if (disk->luDataFileNameValid) { 11369585STim.Szeto@Sun.COM dataFileNameLen = strlen(disk->luDataFileName); 11379585STim.Szeto@Sun.COM } else { 11389585STim.Szeto@Sun.COM (void) close(fd); 11399585STim.Szeto@Sun.COM return (STMF_ERROR_MISSING_PROP_VAL); 11409585STim.Szeto@Sun.COM } 11419585STim.Szeto@Sun.COM 11429585STim.Szeto@Sun.COM sluBufSize += dataFileNameLen + 1; 11439585STim.Szeto@Sun.COM 11449585STim.Szeto@Sun.COM if (disk->luMetaFileNameValid) { 11459585STim.Szeto@Sun.COM metaFileNameLen = strlen(disk->luMetaFileName); 11469585STim.Szeto@Sun.COM sluBufSize += metaFileNameLen + 1; 11479585STim.Szeto@Sun.COM } 11489585STim.Szeto@Sun.COM 11499585STim.Szeto@Sun.COM serialNumLen = strlen(disk->serialNum); 11509585STim.Szeto@Sun.COM sluBufSize += serialNumLen; 11519585STim.Szeto@Sun.COM 11529585STim.Szeto@Sun.COM if (disk->luAliasValid) { 11539585STim.Szeto@Sun.COM luAliasLen = strlen(disk->luAlias); 11549585STim.Szeto@Sun.COM sluBufSize += luAliasLen + 1; 11559585STim.Szeto@Sun.COM } 11569585STim.Szeto@Sun.COM 115710113SNattuvetty.Bhavyan@Sun.COM if (disk->luMgmtUrlValid) { 115810113SNattuvetty.Bhavyan@Sun.COM luMgmtUrlLen = strlen(disk->luMgmtUrl); 115910113SNattuvetty.Bhavyan@Sun.COM sluBufSize += luMgmtUrlLen + 1; 116010113SNattuvetty.Bhavyan@Sun.COM } 116110113SNattuvetty.Bhavyan@Sun.COM 11629585STim.Szeto@Sun.COM /* 11639585STim.Szeto@Sun.COM * 8 is the size of the buffer set aside for 11649585STim.Szeto@Sun.COM * concatenation of variable length fields 11659585STim.Szeto@Sun.COM */ 11669585STim.Szeto@Sun.COM sbdLu = (sbd_create_and_reg_lu_t *)calloc(1, 11679585STim.Szeto@Sun.COM sizeof (sbd_create_and_reg_lu_t) + sluBufSize - 8); 11689585STim.Szeto@Sun.COM if (sbdLu == NULL) { 11699585STim.Szeto@Sun.COM return (STMF_ERROR_NOMEM); 11709585STim.Szeto@Sun.COM } 11719585STim.Szeto@Sun.COM 11729585STim.Szeto@Sun.COM sbdLu->slu_struct_size = sizeof (sbd_create_and_reg_lu_t) + 11739585STim.Szeto@Sun.COM sluBufSize - 8; 11749585STim.Szeto@Sun.COM 11759585STim.Szeto@Sun.COM if (metaFileNameLen) { 11769585STim.Szeto@Sun.COM sbdLu->slu_meta_fname_valid = 1; 11779585STim.Szeto@Sun.COM sbdLu->slu_meta_fname_off = bufOffset; 11789585STim.Szeto@Sun.COM bcopy(disk->luMetaFileName, &(sbdLu->slu_buf[bufOffset]), 11799585STim.Szeto@Sun.COM metaFileNameLen + 1); 11809585STim.Szeto@Sun.COM bufOffset += metaFileNameLen + 1; 11819585STim.Szeto@Sun.COM } 11829585STim.Szeto@Sun.COM 11839585STim.Szeto@Sun.COM bcopy(disk->luDataFileName, &(sbdLu->slu_buf[bufOffset]), 11849585STim.Szeto@Sun.COM dataFileNameLen + 1); 11859585STim.Szeto@Sun.COM sbdLu->slu_data_fname_off = bufOffset; 11869585STim.Szeto@Sun.COM bufOffset += dataFileNameLen + 1; 11879585STim.Szeto@Sun.COM 11889585STim.Szeto@Sun.COM /* currently, serial # is not passed null terminated to the driver */ 11899585STim.Szeto@Sun.COM if (disk->serialNumValid) { 11909585STim.Szeto@Sun.COM sbdLu->slu_serial_valid = 1; 11919585STim.Szeto@Sun.COM sbdLu->slu_serial_off = bufOffset; 11929585STim.Szeto@Sun.COM sbdLu->slu_serial_size = serialNumLen; 11939585STim.Szeto@Sun.COM bcopy(disk->serialNum, &(sbdLu->slu_buf[bufOffset]), 11949585STim.Szeto@Sun.COM serialNumLen); 11959585STim.Szeto@Sun.COM bufOffset += serialNumLen; 11969585STim.Szeto@Sun.COM } 11979585STim.Szeto@Sun.COM 11989585STim.Szeto@Sun.COM if (disk->luAliasValid) { 11999585STim.Szeto@Sun.COM sbdLu->slu_alias_valid = 1; 12009585STim.Szeto@Sun.COM sbdLu->slu_alias_off = bufOffset; 12019585STim.Szeto@Sun.COM bcopy(disk->luAlias, &(sbdLu->slu_buf[bufOffset]), 12029585STim.Szeto@Sun.COM luAliasLen + 1); 12039585STim.Szeto@Sun.COM bufOffset += luAliasLen + 1; 12049585STim.Szeto@Sun.COM } 12059585STim.Szeto@Sun.COM 120610113SNattuvetty.Bhavyan@Sun.COM if (disk->luMgmtUrlValid) { 120710113SNattuvetty.Bhavyan@Sun.COM sbdLu->slu_mgmt_url_valid = 1; 120810113SNattuvetty.Bhavyan@Sun.COM sbdLu->slu_mgmt_url_off = bufOffset; 120910113SNattuvetty.Bhavyan@Sun.COM bcopy(disk->luMgmtUrl, &(sbdLu->slu_buf[bufOffset]), 121010113SNattuvetty.Bhavyan@Sun.COM luMgmtUrlLen + 1); 121110113SNattuvetty.Bhavyan@Sun.COM bufOffset += luMgmtUrlLen + 1; 121210113SNattuvetty.Bhavyan@Sun.COM } 121310113SNattuvetty.Bhavyan@Sun.COM 12149585STim.Szeto@Sun.COM if (disk->luSizeValid) { 12159585STim.Szeto@Sun.COM sbdLu->slu_lu_size_valid = 1; 12169585STim.Szeto@Sun.COM sbdLu->slu_lu_size = disk->luSize; 12179585STim.Szeto@Sun.COM } 12189585STim.Szeto@Sun.COM 12199585STim.Szeto@Sun.COM if (disk->luGuidValid) { 12209585STim.Szeto@Sun.COM sbdLu->slu_guid_valid = 1; 12219585STim.Szeto@Sun.COM bcopy(disk->luGuid, sbdLu->slu_guid, sizeof (disk->luGuid)); 12229585STim.Szeto@Sun.COM } 12239585STim.Szeto@Sun.COM 12249585STim.Szeto@Sun.COM if (disk->vidValid) { 12259585STim.Szeto@Sun.COM sbdLu->slu_vid_valid = 1; 12269585STim.Szeto@Sun.COM bcopy(disk->vid, sbdLu->slu_vid, sizeof (disk->vid)); 12279585STim.Szeto@Sun.COM } 12289585STim.Szeto@Sun.COM 12299585STim.Szeto@Sun.COM if (disk->pidValid) { 12309585STim.Szeto@Sun.COM sbdLu->slu_pid_valid = 1; 12319585STim.Szeto@Sun.COM bcopy(disk->pid, sbdLu->slu_pid, sizeof (disk->pid)); 12329585STim.Szeto@Sun.COM } 12339585STim.Szeto@Sun.COM 12349585STim.Szeto@Sun.COM if (disk->revValid) { 12359585STim.Szeto@Sun.COM sbdLu->slu_rev_valid = 1; 12369585STim.Szeto@Sun.COM bcopy(disk->rev, sbdLu->slu_rev, sizeof (disk->rev)); 12379585STim.Szeto@Sun.COM } 12389585STim.Szeto@Sun.COM 12399585STim.Szeto@Sun.COM if (disk->companyIdValid) { 12409585STim.Szeto@Sun.COM sbdLu->slu_company_id_valid = 1; 12419585STim.Szeto@Sun.COM sbdLu->slu_company_id = disk->companyId; 12429585STim.Szeto@Sun.COM } 12439585STim.Szeto@Sun.COM 12449585STim.Szeto@Sun.COM if (disk->blkSizeValid) { 12459585STim.Szeto@Sun.COM sbdLu->slu_blksize_valid = 1; 12469585STim.Szeto@Sun.COM sbdLu->slu_blksize = disk->blkSize; 12479585STim.Szeto@Sun.COM } 12489585STim.Szeto@Sun.COM 12499585STim.Szeto@Sun.COM if (disk->writeProtectEnableValid) { 12509585STim.Szeto@Sun.COM if (disk->writeProtectEnable) { 12519585STim.Szeto@Sun.COM sbdLu->slu_write_protected = 1; 12529585STim.Szeto@Sun.COM } 12539585STim.Szeto@Sun.COM } 12549585STim.Szeto@Sun.COM 12559585STim.Szeto@Sun.COM if (disk->writebackCacheDisableValid) { 12569585STim.Szeto@Sun.COM sbdLu->slu_writeback_cache_disable_valid = 1; 12579585STim.Szeto@Sun.COM if (disk->writebackCacheDisable) { 12589585STim.Szeto@Sun.COM sbdLu->slu_writeback_cache_disable = 1; 12599585STim.Szeto@Sun.COM } 12609585STim.Szeto@Sun.COM } 12619585STim.Szeto@Sun.COM 12629585STim.Szeto@Sun.COM sbdIoctl.stmf_version = STMF_VERSION_1; 12639585STim.Szeto@Sun.COM sbdIoctl.stmf_ibuf_size = sbdLu->slu_struct_size; 12649585STim.Szeto@Sun.COM sbdIoctl.stmf_ibuf = (uint64_t)(unsigned long)sbdLu; 12659585STim.Szeto@Sun.COM sbdIoctl.stmf_obuf_size = sbdLu->slu_struct_size; 12669585STim.Szeto@Sun.COM sbdIoctl.stmf_obuf = (uint64_t)(unsigned long)sbdLu; 12679585STim.Szeto@Sun.COM 12689585STim.Szeto@Sun.COM ioctlRet = ioctl(fd, SBD_IOCTL_CREATE_AND_REGISTER_LU, &sbdIoctl); 12699585STim.Szeto@Sun.COM if (ioctlRet != 0) { 12709585STim.Szeto@Sun.COM savedErrno = errno; 12719585STim.Szeto@Sun.COM switch (savedErrno) { 12729585STim.Szeto@Sun.COM case EBUSY: 12739585STim.Szeto@Sun.COM ret = STMF_ERROR_BUSY; 12749585STim.Szeto@Sun.COM break; 12759585STim.Szeto@Sun.COM case EPERM: 12769585STim.Szeto@Sun.COM case EACCES: 12779585STim.Szeto@Sun.COM ret = STMF_ERROR_PERM; 12789585STim.Szeto@Sun.COM break; 12799585STim.Szeto@Sun.COM default: 12809585STim.Szeto@Sun.COM diskError(sbdIoctl.stmf_error, &ret); 12819585STim.Szeto@Sun.COM if (ret == STMF_STATUS_ERROR) { 12829585STim.Szeto@Sun.COM syslog(LOG_DEBUG, 12839585STim.Szeto@Sun.COM "createDiskLu:ioctl " 12849585STim.Szeto@Sun.COM "error(%d) (%d) (%d)", ioctlRet, 12859585STim.Szeto@Sun.COM sbdIoctl.stmf_error, savedErrno); 12869585STim.Szeto@Sun.COM } 12879585STim.Szeto@Sun.COM break; 12889585STim.Szeto@Sun.COM } 12899585STim.Szeto@Sun.COM } 12909585STim.Szeto@Sun.COM 12919585STim.Szeto@Sun.COM if (ret != STMF_STATUS_SUCCESS) { 12929585STim.Szeto@Sun.COM goto done; 12939585STim.Szeto@Sun.COM } 12949585STim.Szeto@Sun.COM 12959585STim.Szeto@Sun.COM /* 12969585STim.Szeto@Sun.COM * on success, copy the resulting guid into the caller's guid if not 12979585STim.Szeto@Sun.COM * NULL 12989585STim.Szeto@Sun.COM */ 12999585STim.Szeto@Sun.COM if (createdGuid) { 13009585STim.Szeto@Sun.COM bcopy(sbdLu->slu_guid, createdGuid->guid, 13019585STim.Szeto@Sun.COM sizeof (sbdLu->slu_guid)); 13029585STim.Szeto@Sun.COM } 13039585STim.Szeto@Sun.COM 13049585STim.Szeto@Sun.COM bcopy(sbdLu->slu_guid, guid.guid, sizeof (sbdLu->slu_guid)); 13059585STim.Szeto@Sun.COM if (disk->luMetaFileNameValid) { 13069585STim.Szeto@Sun.COM ret = addGuidToDiskStore(&guid, disk->luMetaFileName); 13079585STim.Szeto@Sun.COM } else { 13089585STim.Szeto@Sun.COM ret = addGuidToDiskStore(&guid, disk->luDataFileName); 13099585STim.Szeto@Sun.COM } 13109585STim.Szeto@Sun.COM done: 13119585STim.Szeto@Sun.COM free(sbdLu); 13129585STim.Szeto@Sun.COM (void) close(fd); 13139585STim.Szeto@Sun.COM return (ret); 13149585STim.Szeto@Sun.COM } 13159585STim.Szeto@Sun.COM 13169585STim.Szeto@Sun.COM 13179585STim.Szeto@Sun.COM /* 13189585STim.Szeto@Sun.COM * stmfImportLu 13199585STim.Szeto@Sun.COM * 13209585STim.Szeto@Sun.COM * Purpose: Import a previously created logical unit 13219585STim.Szeto@Sun.COM * 13229585STim.Szeto@Sun.COM * dType - Type of logical unit 13239585STim.Szeto@Sun.COM * Can be: STMF_DISK 13249585STim.Szeto@Sun.COM * 13259585STim.Szeto@Sun.COM * luGuid - If non-NULL, on success, contains the guid of the imported logical 13269585STim.Szeto@Sun.COM * unit 13279585STim.Szeto@Sun.COM * 13289585STim.Szeto@Sun.COM * fname - A file name where the metadata resides 13299585STim.Szeto@Sun.COM * 13309585STim.Szeto@Sun.COM */ 13319585STim.Szeto@Sun.COM int 13329585STim.Szeto@Sun.COM stmfImportLu(uint16_t dType, char *fname, stmfGuid *luGuid) 13339585STim.Szeto@Sun.COM { 13349585STim.Szeto@Sun.COM int ret = STMF_STATUS_SUCCESS; 13359585STim.Szeto@Sun.COM 13369585STim.Szeto@Sun.COM if (dType == STMF_DISK) { 13379585STim.Szeto@Sun.COM ret = importDiskLu(fname, luGuid); 13389585STim.Szeto@Sun.COM } else { 13399585STim.Szeto@Sun.COM return (STMF_ERROR_INVALID_ARG); 13409585STim.Szeto@Sun.COM } 13419585STim.Szeto@Sun.COM 13429585STim.Szeto@Sun.COM return (ret); 13439585STim.Szeto@Sun.COM } 13449585STim.Szeto@Sun.COM 13459585STim.Szeto@Sun.COM /* 13469585STim.Szeto@Sun.COM * importDiskLu 13479585STim.Szeto@Sun.COM * 13489585STim.Szeto@Sun.COM * filename - filename to import 13499585STim.Szeto@Sun.COM * createdGuid - if not NULL, on success contains the imported guid 13509585STim.Szeto@Sun.COM * 13519585STim.Szeto@Sun.COM */ 13529585STim.Szeto@Sun.COM static int 13539585STim.Szeto@Sun.COM importDiskLu(char *fname, stmfGuid *createdGuid) 13549585STim.Szeto@Sun.COM { 13559585STim.Szeto@Sun.COM int ret = STMF_STATUS_SUCCESS; 13569585STim.Szeto@Sun.COM int fd = 0; 13579585STim.Szeto@Sun.COM int ioctlRet; 13589585STim.Szeto@Sun.COM int savedErrno; 13599585STim.Szeto@Sun.COM int metaFileNameLen; 13609585STim.Szeto@Sun.COM stmfGuid iGuid; 13619585STim.Szeto@Sun.COM int iluBufSize = 0; 13629585STim.Szeto@Sun.COM sbd_import_lu_t *sbdLu = NULL; 13639585STim.Szeto@Sun.COM stmf_iocdata_t sbdIoctl = {0}; 13649585STim.Szeto@Sun.COM 13659585STim.Szeto@Sun.COM if (fname == NULL) { 13669585STim.Szeto@Sun.COM return (STMF_ERROR_INVALID_ARG); 13679585STim.Szeto@Sun.COM } 13689585STim.Szeto@Sun.COM 13699585STim.Szeto@Sun.COM /* 13709585STim.Szeto@Sun.COM * Open control node for sbd 13719585STim.Szeto@Sun.COM */ 13729585STim.Szeto@Sun.COM if ((ret = openSbd(OPEN_SBD, &fd)) != STMF_STATUS_SUCCESS) 13739585STim.Szeto@Sun.COM return (ret); 13749585STim.Szeto@Sun.COM 13759585STim.Szeto@Sun.COM metaFileNameLen = strlen(fname); 13769585STim.Szeto@Sun.COM iluBufSize += metaFileNameLen + 1; 13779585STim.Szeto@Sun.COM 13789585STim.Szeto@Sun.COM /* 13799585STim.Szeto@Sun.COM * 8 is the size of the buffer set aside for 13809585STim.Szeto@Sun.COM * concatenation of variable length fields 13819585STim.Szeto@Sun.COM */ 13829585STim.Szeto@Sun.COM sbdLu = (sbd_import_lu_t *)calloc(1, 13839585STim.Szeto@Sun.COM sizeof (sbd_import_lu_t) + iluBufSize - 8); 13849585STim.Szeto@Sun.COM if (sbdLu == NULL) { 13859585STim.Szeto@Sun.COM (void) close(fd); 13869585STim.Szeto@Sun.COM return (STMF_ERROR_NOMEM); 13879585STim.Szeto@Sun.COM } 13889585STim.Szeto@Sun.COM 13899585STim.Szeto@Sun.COM /* 13909585STim.Szeto@Sun.COM * Accept either a data file or meta data file. 13919585STim.Szeto@Sun.COM * sbd will do the right thing here either way. 13929585STim.Szeto@Sun.COM * i.e. if it's a data file, it assumes that the 13939585STim.Szeto@Sun.COM * meta data is shared with the data. 13949585STim.Szeto@Sun.COM */ 13959585STim.Szeto@Sun.COM (void) strncpy(sbdLu->ilu_meta_fname, fname, metaFileNameLen); 13969585STim.Szeto@Sun.COM 13979585STim.Szeto@Sun.COM sbdLu->ilu_struct_size = sizeof (sbd_import_lu_t) + iluBufSize - 8; 13989585STim.Szeto@Sun.COM 13999585STim.Szeto@Sun.COM sbdIoctl.stmf_version = STMF_VERSION_1; 14009585STim.Szeto@Sun.COM sbdIoctl.stmf_ibuf_size = sbdLu->ilu_struct_size; 14019585STim.Szeto@Sun.COM sbdIoctl.stmf_ibuf = (uint64_t)(unsigned long)sbdLu; 14029585STim.Szeto@Sun.COM sbdIoctl.stmf_obuf_size = sbdLu->ilu_struct_size; 14039585STim.Szeto@Sun.COM sbdIoctl.stmf_obuf = (uint64_t)(unsigned long)sbdLu; 14049585STim.Szeto@Sun.COM 14059585STim.Szeto@Sun.COM ioctlRet = ioctl(fd, SBD_IOCTL_IMPORT_LU, &sbdIoctl); 14069585STim.Szeto@Sun.COM if (ioctlRet != 0) { 14079585STim.Szeto@Sun.COM savedErrno = errno; 14089585STim.Szeto@Sun.COM switch (savedErrno) { 14099585STim.Szeto@Sun.COM case EBUSY: 14109585STim.Szeto@Sun.COM ret = STMF_ERROR_BUSY; 14119585STim.Szeto@Sun.COM break; 14129585STim.Szeto@Sun.COM case EPERM: 14139585STim.Szeto@Sun.COM case EACCES: 14149585STim.Szeto@Sun.COM ret = STMF_ERROR_PERM; 14159585STim.Szeto@Sun.COM break; 14169585STim.Szeto@Sun.COM default: 14179585STim.Szeto@Sun.COM diskError(sbdIoctl.stmf_error, &ret); 14189585STim.Szeto@Sun.COM if (ret == STMF_STATUS_ERROR) { 14199585STim.Szeto@Sun.COM syslog(LOG_DEBUG, 14209585STim.Szeto@Sun.COM "importDiskLu:ioctl " 14219585STim.Szeto@Sun.COM "error(%d) (%d) (%d)", ioctlRet, 14229585STim.Szeto@Sun.COM sbdIoctl.stmf_error, savedErrno); 14239585STim.Szeto@Sun.COM } 14249585STim.Szeto@Sun.COM break; 14259585STim.Szeto@Sun.COM } 14269585STim.Szeto@Sun.COM } 14279585STim.Szeto@Sun.COM 14289585STim.Szeto@Sun.COM if (ret != STMF_STATUS_SUCCESS) { 14299585STim.Szeto@Sun.COM goto done; 14309585STim.Szeto@Sun.COM } 14319585STim.Szeto@Sun.COM 14329585STim.Szeto@Sun.COM /* 14339585STim.Szeto@Sun.COM * on success, copy the resulting guid into the caller's guid if not 14349585STim.Szeto@Sun.COM * NULL and add it to the persistent store for sbd 14359585STim.Szeto@Sun.COM */ 14369585STim.Szeto@Sun.COM if (createdGuid) { 14379585STim.Szeto@Sun.COM bcopy(sbdLu->ilu_ret_guid, createdGuid->guid, 14389585STim.Szeto@Sun.COM sizeof (sbdLu->ilu_ret_guid)); 14399585STim.Szeto@Sun.COM ret = addGuidToDiskStore(createdGuid, fname); 14409585STim.Szeto@Sun.COM } else { 14419585STim.Szeto@Sun.COM bcopy(sbdLu->ilu_ret_guid, iGuid.guid, 14429585STim.Szeto@Sun.COM sizeof (sbdLu->ilu_ret_guid)); 14439585STim.Szeto@Sun.COM ret = addGuidToDiskStore(&iGuid, fname); 14449585STim.Szeto@Sun.COM } 14459585STim.Szeto@Sun.COM done: 14469585STim.Szeto@Sun.COM free(sbdLu); 14479585STim.Szeto@Sun.COM (void) close(fd); 14489585STim.Szeto@Sun.COM return (ret); 14499585STim.Szeto@Sun.COM } 14509585STim.Szeto@Sun.COM 14519585STim.Szeto@Sun.COM /* 14529585STim.Szeto@Sun.COM * diskError 14539585STim.Szeto@Sun.COM * 14549585STim.Szeto@Sun.COM * Purpose: Translate sbd driver error 14559585STim.Szeto@Sun.COM */ 14569585STim.Szeto@Sun.COM static void 14579585STim.Szeto@Sun.COM diskError(uint32_t stmfError, int *ret) 14589585STim.Szeto@Sun.COM { 14599585STim.Szeto@Sun.COM switch (stmfError) { 14609585STim.Szeto@Sun.COM case SBD_RET_META_CREATION_FAILED: 14619585STim.Szeto@Sun.COM case SBD_RET_ZFS_META_CREATE_FAILED: 14629585STim.Szeto@Sun.COM *ret = STMF_ERROR_META_CREATION; 14639585STim.Szeto@Sun.COM break; 14649585STim.Szeto@Sun.COM case SBD_RET_INVALID_BLKSIZE: 14659585STim.Szeto@Sun.COM *ret = STMF_ERROR_INVALID_BLKSIZE; 14669585STim.Szeto@Sun.COM break; 14679585STim.Szeto@Sun.COM case SBD_RET_FILE_ALREADY_REGISTERED: 14689585STim.Szeto@Sun.COM *ret = STMF_ERROR_FILE_IN_USE; 14699585STim.Szeto@Sun.COM break; 14709585STim.Szeto@Sun.COM case SBD_RET_GUID_ALREADY_REGISTERED: 14719585STim.Szeto@Sun.COM *ret = STMF_ERROR_GUID_IN_USE; 14729585STim.Szeto@Sun.COM break; 14739585STim.Szeto@Sun.COM case SBD_RET_META_PATH_NOT_ABSOLUTE: 14749585STim.Szeto@Sun.COM case SBD_RET_META_FILE_LOOKUP_FAILED: 14759585STim.Szeto@Sun.COM case SBD_RET_META_FILE_OPEN_FAILED: 14769585STim.Szeto@Sun.COM case SBD_RET_META_FILE_GETATTR_FAILED: 14779585STim.Szeto@Sun.COM case SBD_RET_NO_META: 14789585STim.Szeto@Sun.COM *ret = STMF_ERROR_META_FILE_NAME; 14799585STim.Szeto@Sun.COM break; 14809585STim.Szeto@Sun.COM case SBD_RET_DATA_PATH_NOT_ABSOLUTE: 14819585STim.Szeto@Sun.COM case SBD_RET_DATA_FILE_LOOKUP_FAILED: 14829585STim.Szeto@Sun.COM case SBD_RET_DATA_FILE_OPEN_FAILED: 14839585STim.Szeto@Sun.COM case SBD_RET_DATA_FILE_GETATTR_FAILED: 14849585STim.Szeto@Sun.COM *ret = STMF_ERROR_DATA_FILE_NAME; 14859585STim.Szeto@Sun.COM break; 14869585STim.Szeto@Sun.COM case SBD_RET_FILE_SIZE_ERROR: 14879585STim.Szeto@Sun.COM *ret = STMF_ERROR_FILE_SIZE_INVALID; 14889585STim.Szeto@Sun.COM break; 14899585STim.Szeto@Sun.COM case SBD_RET_SIZE_OUT_OF_RANGE: 14909585STim.Szeto@Sun.COM *ret = STMF_ERROR_SIZE_OUT_OF_RANGE; 14919585STim.Szeto@Sun.COM break; 14929585STim.Szeto@Sun.COM case SBD_RET_LU_BUSY: 14939585STim.Szeto@Sun.COM *ret = STMF_ERROR_LU_BUSY; 14949585STim.Szeto@Sun.COM break; 14959585STim.Szeto@Sun.COM case SBD_RET_WRITE_CACHE_SET_FAILED: 14969585STim.Szeto@Sun.COM *ret = STMF_ERROR_WRITE_CACHE_SET; 14979585STim.Szeto@Sun.COM break; 1498*10725SJohn.Forte@Sun.COM case SBD_RET_ACCESS_STATE_FAILED: 1499*10725SJohn.Forte@Sun.COM *ret = STMF_ERROR_ACCESS_STATE_SET; 1500*10725SJohn.Forte@Sun.COM break; 15019585STim.Szeto@Sun.COM default: 15029585STim.Szeto@Sun.COM *ret = STMF_STATUS_ERROR; 15039585STim.Szeto@Sun.COM break; 15049585STim.Szeto@Sun.COM } 15059585STim.Szeto@Sun.COM } 15069585STim.Szeto@Sun.COM 15079585STim.Szeto@Sun.COM /* 15089585STim.Szeto@Sun.COM * Creates a logical unit resource of type STMF_DISK. 15099585STim.Szeto@Sun.COM * 15109585STim.Szeto@Sun.COM * No defaults should be set here as all defaults are derived from the 15119585STim.Szeto@Sun.COM * driver's default settings. 15129585STim.Szeto@Sun.COM */ 15139585STim.Szeto@Sun.COM static int 15149585STim.Szeto@Sun.COM createDiskResource(luResourceImpl *hdl) 15159585STim.Szeto@Sun.COM { 15169585STim.Szeto@Sun.COM hdl->type = STMF_DISK; 15179585STim.Szeto@Sun.COM 15189585STim.Szeto@Sun.COM hdl->resource = calloc(1, sizeof (diskResource)); 15199585STim.Szeto@Sun.COM if (hdl->resource == NULL) { 15209585STim.Szeto@Sun.COM return (STMF_ERROR_NOMEM); 15219585STim.Szeto@Sun.COM } 15229585STim.Szeto@Sun.COM 15239585STim.Szeto@Sun.COM return (STMF_STATUS_SUCCESS); 15249585STim.Szeto@Sun.COM } 15259585STim.Szeto@Sun.COM 15269585STim.Szeto@Sun.COM /* 15279585STim.Szeto@Sun.COM * stmfDeleteLu 15289585STim.Szeto@Sun.COM * 15299585STim.Szeto@Sun.COM * Purpose: Delete a logical unit 15309585STim.Szeto@Sun.COM * 15319585STim.Szeto@Sun.COM * hdl - handle to logical unit resource created via stmfCreateLuResource 15329585STim.Szeto@Sun.COM * 15339585STim.Szeto@Sun.COM * luGuid - If non-NULL, on success, contains the guid of the created logical 15349585STim.Szeto@Sun.COM * unit 15359585STim.Szeto@Sun.COM */ 15369585STim.Szeto@Sun.COM int 15379585STim.Szeto@Sun.COM stmfDeleteLu(stmfGuid *luGuid) 15389585STim.Szeto@Sun.COM { 15399585STim.Szeto@Sun.COM int ret = STMF_STATUS_SUCCESS; 15409585STim.Szeto@Sun.COM stmfLogicalUnitProperties luProps; 15419585STim.Szeto@Sun.COM 15429585STim.Szeto@Sun.COM if (luGuid == NULL) { 15439585STim.Szeto@Sun.COM return (STMF_ERROR_INVALID_ARG); 15449585STim.Szeto@Sun.COM } 15459585STim.Szeto@Sun.COM 15469585STim.Szeto@Sun.COM /* Check logical unit provider name to call correct dtype function */ 15479585STim.Szeto@Sun.COM if ((ret = stmfGetLogicalUnitProperties(luGuid, &luProps)) 15489585STim.Szeto@Sun.COM != STMF_STATUS_SUCCESS) { 15499585STim.Szeto@Sun.COM return (ret); 15509585STim.Szeto@Sun.COM } else { 15519585STim.Szeto@Sun.COM if (strcmp(luProps.providerName, "sbd") == 0) { 15529585STim.Szeto@Sun.COM ret = deleteDiskLu(luGuid); 15539585STim.Szeto@Sun.COM } else if (luProps.status == STMF_LOGICAL_UNIT_UNREGISTERED) { 15549585STim.Szeto@Sun.COM return (STMF_ERROR_NOT_FOUND); 15559585STim.Szeto@Sun.COM } else { 15569585STim.Szeto@Sun.COM return (STMF_ERROR_INVALID_ARG); 15579585STim.Szeto@Sun.COM } 15589585STim.Szeto@Sun.COM } 15599585STim.Szeto@Sun.COM 15609585STim.Szeto@Sun.COM return (ret); 15619585STim.Szeto@Sun.COM } 15629585STim.Szeto@Sun.COM 15639585STim.Szeto@Sun.COM static int 15649585STim.Szeto@Sun.COM deleteDiskLu(stmfGuid *luGuid) 15659585STim.Szeto@Sun.COM { 15669585STim.Szeto@Sun.COM int ret = STMF_STATUS_SUCCESS; 15679585STim.Szeto@Sun.COM int fd; 15689585STim.Szeto@Sun.COM int savedErrno; 15699585STim.Szeto@Sun.COM int ioctlRet; 15709585STim.Szeto@Sun.COM sbd_delete_lu_t deleteLu = {0}; 15719585STim.Szeto@Sun.COM 15729585STim.Szeto@Sun.COM stmf_iocdata_t sbdIoctl = {0}; 15739585STim.Szeto@Sun.COM 15749585STim.Szeto@Sun.COM /* 15759585STim.Szeto@Sun.COM * Open control node for sbd 15769585STim.Szeto@Sun.COM */ 15779585STim.Szeto@Sun.COM if ((ret = openSbd(OPEN_SBD, &fd)) != STMF_STATUS_SUCCESS) 15789585STim.Szeto@Sun.COM return (ret); 15799585STim.Szeto@Sun.COM 15809585STim.Szeto@Sun.COM ret = removeGuidFromDiskStore(luGuid); 15819585STim.Szeto@Sun.COM if (ret != STMF_STATUS_SUCCESS) { 15829585STim.Szeto@Sun.COM goto done; 15839585STim.Szeto@Sun.COM } 15849585STim.Szeto@Sun.COM 15859585STim.Szeto@Sun.COM bcopy(luGuid, deleteLu.dlu_guid, sizeof (deleteLu.dlu_guid)); 15869585STim.Szeto@Sun.COM deleteLu.dlu_by_guid = 1; 15879585STim.Szeto@Sun.COM 15889585STim.Szeto@Sun.COM sbdIoctl.stmf_version = STMF_VERSION_1; 15899585STim.Szeto@Sun.COM sbdIoctl.stmf_ibuf_size = sizeof (deleteLu); 15909585STim.Szeto@Sun.COM sbdIoctl.stmf_ibuf = (uint64_t)(unsigned long)&deleteLu; 15919585STim.Szeto@Sun.COM ioctlRet = ioctl(fd, SBD_IOCTL_DELETE_LU, &sbdIoctl); 15929585STim.Szeto@Sun.COM if (ioctlRet != 0) { 15939585STim.Szeto@Sun.COM savedErrno = errno; 15949585STim.Szeto@Sun.COM switch (savedErrno) { 15959585STim.Szeto@Sun.COM case EBUSY: 15969585STim.Szeto@Sun.COM ret = STMF_ERROR_BUSY; 15979585STim.Szeto@Sun.COM break; 15989585STim.Szeto@Sun.COM case EPERM: 15999585STim.Szeto@Sun.COM case EACCES: 16009585STim.Szeto@Sun.COM ret = STMF_ERROR_PERM; 16019585STim.Szeto@Sun.COM break; 16029585STim.Szeto@Sun.COM case ENOENT: 16039585STim.Szeto@Sun.COM ret = STMF_ERROR_NOT_FOUND; 16049585STim.Szeto@Sun.COM break; 16059585STim.Szeto@Sun.COM default: 16069585STim.Szeto@Sun.COM syslog(LOG_DEBUG, 16079585STim.Szeto@Sun.COM "deleteDiskLu:ioctl error(%d) (%d) (%d)", 16089585STim.Szeto@Sun.COM ioctlRet, sbdIoctl.stmf_error, savedErrno); 16099585STim.Szeto@Sun.COM ret = STMF_STATUS_ERROR; 16109585STim.Szeto@Sun.COM break; 16119585STim.Szeto@Sun.COM } 16129585STim.Szeto@Sun.COM } 16139585STim.Szeto@Sun.COM 16149585STim.Szeto@Sun.COM done: 16159585STim.Szeto@Sun.COM (void) close(fd); 16169585STim.Szeto@Sun.COM return (ret); 16179585STim.Szeto@Sun.COM } 16189585STim.Szeto@Sun.COM 16199585STim.Szeto@Sun.COM /* 1620*10725SJohn.Forte@Sun.COM * stmfLuStandby 1621*10725SJohn.Forte@Sun.COM * 1622*10725SJohn.Forte@Sun.COM * Purpose: Sets access state to standby 1623*10725SJohn.Forte@Sun.COM * 1624*10725SJohn.Forte@Sun.COM * luGuid - guid of registered logical unit 1625*10725SJohn.Forte@Sun.COM * 1626*10725SJohn.Forte@Sun.COM */ 1627*10725SJohn.Forte@Sun.COM int 1628*10725SJohn.Forte@Sun.COM stmfLuStandby(stmfGuid *luGuid) 1629*10725SJohn.Forte@Sun.COM { 1630*10725SJohn.Forte@Sun.COM int ret = STMF_STATUS_SUCCESS; 1631*10725SJohn.Forte@Sun.COM stmfLogicalUnitProperties luProps; 1632*10725SJohn.Forte@Sun.COM 1633*10725SJohn.Forte@Sun.COM if (luGuid == NULL) { 1634*10725SJohn.Forte@Sun.COM return (STMF_ERROR_INVALID_ARG); 1635*10725SJohn.Forte@Sun.COM } 1636*10725SJohn.Forte@Sun.COM 1637*10725SJohn.Forte@Sun.COM /* Check logical unit provider name to call correct dtype function */ 1638*10725SJohn.Forte@Sun.COM if ((ret = stmfGetLogicalUnitProperties(luGuid, &luProps)) 1639*10725SJohn.Forte@Sun.COM != STMF_STATUS_SUCCESS) { 1640*10725SJohn.Forte@Sun.COM return (ret); 1641*10725SJohn.Forte@Sun.COM } else { 1642*10725SJohn.Forte@Sun.COM if (strcmp(luProps.providerName, "sbd") == 0) { 1643*10725SJohn.Forte@Sun.COM ret = setDiskStandby(luGuid); 1644*10725SJohn.Forte@Sun.COM } else if (luProps.status == STMF_LOGICAL_UNIT_UNREGISTERED) { 1645*10725SJohn.Forte@Sun.COM return (STMF_ERROR_NOT_FOUND); 1646*10725SJohn.Forte@Sun.COM } else { 1647*10725SJohn.Forte@Sun.COM return (STMF_ERROR_INVALID_ARG); 1648*10725SJohn.Forte@Sun.COM } 1649*10725SJohn.Forte@Sun.COM } 1650*10725SJohn.Forte@Sun.COM 1651*10725SJohn.Forte@Sun.COM return (ret); 1652*10725SJohn.Forte@Sun.COM } 1653*10725SJohn.Forte@Sun.COM 1654*10725SJohn.Forte@Sun.COM static int 1655*10725SJohn.Forte@Sun.COM setDiskStandby(stmfGuid *luGuid) 1656*10725SJohn.Forte@Sun.COM { 1657*10725SJohn.Forte@Sun.COM int ret = STMF_STATUS_SUCCESS; 1658*10725SJohn.Forte@Sun.COM stmf_iocdata_t sbdIoctl = {0}; 1659*10725SJohn.Forte@Sun.COM sbd_set_lu_standby_t sbdLu = {0}; 1660*10725SJohn.Forte@Sun.COM int ioctlRet; 1661*10725SJohn.Forte@Sun.COM int savedErrno; 1662*10725SJohn.Forte@Sun.COM int fd = 0; 1663*10725SJohn.Forte@Sun.COM 1664*10725SJohn.Forte@Sun.COM /* 1665*10725SJohn.Forte@Sun.COM * Open control node for sbd 1666*10725SJohn.Forte@Sun.COM */ 1667*10725SJohn.Forte@Sun.COM if ((ret = openSbd(OPEN_SBD, &fd)) != STMF_STATUS_SUCCESS) 1668*10725SJohn.Forte@Sun.COM return (ret); 1669*10725SJohn.Forte@Sun.COM 1670*10725SJohn.Forte@Sun.COM bcopy(luGuid, &sbdLu.stlu_guid, sizeof (stmfGuid)); 1671*10725SJohn.Forte@Sun.COM 1672*10725SJohn.Forte@Sun.COM sbdIoctl.stmf_version = STMF_VERSION_1; 1673*10725SJohn.Forte@Sun.COM sbdIoctl.stmf_ibuf_size = sizeof (sbd_set_lu_standby_t); 1674*10725SJohn.Forte@Sun.COM sbdIoctl.stmf_ibuf = (uint64_t)(unsigned long)&sbdLu; 1675*10725SJohn.Forte@Sun.COM 1676*10725SJohn.Forte@Sun.COM ioctlRet = ioctl(fd, SBD_IOCTL_SET_LU_STANDBY, &sbdIoctl); 1677*10725SJohn.Forte@Sun.COM if (ioctlRet != 0) { 1678*10725SJohn.Forte@Sun.COM savedErrno = errno; 1679*10725SJohn.Forte@Sun.COM switch (savedErrno) { 1680*10725SJohn.Forte@Sun.COM case EBUSY: 1681*10725SJohn.Forte@Sun.COM ret = STMF_ERROR_BUSY; 1682*10725SJohn.Forte@Sun.COM break; 1683*10725SJohn.Forte@Sun.COM case EPERM: 1684*10725SJohn.Forte@Sun.COM case EACCES: 1685*10725SJohn.Forte@Sun.COM ret = STMF_ERROR_PERM; 1686*10725SJohn.Forte@Sun.COM break; 1687*10725SJohn.Forte@Sun.COM default: 1688*10725SJohn.Forte@Sun.COM diskError(sbdIoctl.stmf_error, &ret); 1689*10725SJohn.Forte@Sun.COM if (ret == STMF_STATUS_ERROR) { 1690*10725SJohn.Forte@Sun.COM syslog(LOG_DEBUG, 1691*10725SJohn.Forte@Sun.COM "setDiskStandby:ioctl " 1692*10725SJohn.Forte@Sun.COM "error(%d) (%d) (%d)", ioctlRet, 1693*10725SJohn.Forte@Sun.COM sbdIoctl.stmf_error, savedErrno); 1694*10725SJohn.Forte@Sun.COM } 1695*10725SJohn.Forte@Sun.COM break; 1696*10725SJohn.Forte@Sun.COM } 1697*10725SJohn.Forte@Sun.COM } 1698*10725SJohn.Forte@Sun.COM return (ret); 1699*10725SJohn.Forte@Sun.COM } 1700*10725SJohn.Forte@Sun.COM 1701*10725SJohn.Forte@Sun.COM /* 17029585STim.Szeto@Sun.COM * stmfModifyLu 17039585STim.Szeto@Sun.COM * 17049585STim.Szeto@Sun.COM * Purpose: Modify properties of a logical unit 17059585STim.Szeto@Sun.COM * 17069585STim.Szeto@Sun.COM * luGuid - guid of registered logical unit 17079585STim.Szeto@Sun.COM * prop - property to modify 17089585STim.Szeto@Sun.COM * propVal - property value to set 17099585STim.Szeto@Sun.COM * 17109585STim.Szeto@Sun.COM */ 17119585STim.Szeto@Sun.COM int 17129585STim.Szeto@Sun.COM stmfModifyLu(stmfGuid *luGuid, uint32_t prop, const char *propVal) 17139585STim.Szeto@Sun.COM { 17149585STim.Szeto@Sun.COM int ret = STMF_STATUS_SUCCESS; 17159585STim.Szeto@Sun.COM stmfLogicalUnitProperties luProps; 17169585STim.Szeto@Sun.COM 17179585STim.Szeto@Sun.COM if (luGuid == NULL) { 17189585STim.Szeto@Sun.COM return (STMF_ERROR_INVALID_ARG); 17199585STim.Szeto@Sun.COM } 17209585STim.Szeto@Sun.COM 17219585STim.Szeto@Sun.COM /* Check logical unit provider name to call correct dtype function */ 17229585STim.Szeto@Sun.COM if ((ret = stmfGetLogicalUnitProperties(luGuid, &luProps)) 17239585STim.Szeto@Sun.COM != STMF_STATUS_SUCCESS) { 17249585STim.Szeto@Sun.COM return (ret); 17259585STim.Szeto@Sun.COM } else { 17269585STim.Szeto@Sun.COM if (strcmp(luProps.providerName, "sbd") == 0) { 17279585STim.Szeto@Sun.COM ret = modifyDiskLuProp(luGuid, NULL, prop, propVal); 17289585STim.Szeto@Sun.COM } else if (luProps.status == STMF_LOGICAL_UNIT_UNREGISTERED) { 17299585STim.Szeto@Sun.COM return (STMF_ERROR_NOT_FOUND); 17309585STim.Szeto@Sun.COM } else { 17319585STim.Szeto@Sun.COM return (STMF_ERROR_INVALID_ARG); 17329585STim.Szeto@Sun.COM } 17339585STim.Szeto@Sun.COM } 17349585STim.Szeto@Sun.COM 17359585STim.Szeto@Sun.COM return (ret); 17369585STim.Szeto@Sun.COM } 17379585STim.Szeto@Sun.COM 17389585STim.Szeto@Sun.COM /* 17399585STim.Szeto@Sun.COM * stmfModifyLuByFname 17409585STim.Szeto@Sun.COM * 17419585STim.Szeto@Sun.COM * Purpose: Modify a device by filename. Device does not need to be registered. 17429585STim.Szeto@Sun.COM * 17439585STim.Szeto@Sun.COM * dType - type of device to modify 17449585STim.Szeto@Sun.COM * STMF_DISK 17459585STim.Szeto@Sun.COM * 17469585STim.Szeto@Sun.COM * fname - filename or meta filename 17479585STim.Szeto@Sun.COM * prop - valid property identifier 17489585STim.Szeto@Sun.COM * propVal - property value 17499585STim.Szeto@Sun.COM * 17509585STim.Szeto@Sun.COM */ 17519585STim.Szeto@Sun.COM int 17529585STim.Szeto@Sun.COM stmfModifyLuByFname(uint16_t dType, const char *fname, uint32_t prop, 17539585STim.Szeto@Sun.COM const char *propVal) 17549585STim.Szeto@Sun.COM { 17559585STim.Szeto@Sun.COM int ret = STMF_STATUS_SUCCESS; 17569585STim.Szeto@Sun.COM if (fname == NULL) { 17579585STim.Szeto@Sun.COM return (STMF_ERROR_INVALID_ARG); 17589585STim.Szeto@Sun.COM } 17599585STim.Szeto@Sun.COM 17609585STim.Szeto@Sun.COM if (dType == STMF_DISK) { 17619585STim.Szeto@Sun.COM ret = modifyDiskLuProp(NULL, fname, prop, propVal); 17629585STim.Szeto@Sun.COM } else { 17639585STim.Szeto@Sun.COM return (STMF_ERROR_INVALID_ARG); 17649585STim.Szeto@Sun.COM } 17659585STim.Szeto@Sun.COM 17669585STim.Szeto@Sun.COM return (ret); 17679585STim.Szeto@Sun.COM } 17689585STim.Szeto@Sun.COM 17699585STim.Szeto@Sun.COM static int 17709585STim.Szeto@Sun.COM modifyDiskLuProp(stmfGuid *luGuid, const char *fname, uint32_t prop, 17719585STim.Szeto@Sun.COM const char *propVal) 17729585STim.Szeto@Sun.COM { 17739585STim.Szeto@Sun.COM int ret = STMF_STATUS_SUCCESS; 17749585STim.Szeto@Sun.COM luResource hdl = NULL; 17759585STim.Szeto@Sun.COM luResourceImpl *luPropsHdl; 17769585STim.Szeto@Sun.COM 17779585STim.Szeto@Sun.COM ret = stmfCreateLuResource(STMF_DISK, &hdl); 17789585STim.Szeto@Sun.COM if (ret != STMF_STATUS_SUCCESS) { 17799585STim.Szeto@Sun.COM return (ret); 17809585STim.Szeto@Sun.COM } 17819585STim.Szeto@Sun.COM ret = validateModifyDiskProp(prop); 17829585STim.Szeto@Sun.COM if (ret != STMF_STATUS_SUCCESS) { 17839585STim.Szeto@Sun.COM (void) stmfFreeLuResource(hdl); 17849585STim.Szeto@Sun.COM return (STMF_ERROR_INVALID_PROP); 17859585STim.Szeto@Sun.COM } 17869585STim.Szeto@Sun.COM ret = stmfSetLuProp(hdl, prop, propVal); 17879585STim.Szeto@Sun.COM if (ret != STMF_STATUS_SUCCESS) { 17889585STim.Szeto@Sun.COM (void) stmfFreeLuResource(hdl); 17899585STim.Szeto@Sun.COM return (ret); 17909585STim.Szeto@Sun.COM } 17919585STim.Szeto@Sun.COM luPropsHdl = hdl; 17929585STim.Szeto@Sun.COM ret = modifyDiskLu((diskResource *)luPropsHdl->resource, luGuid, fname); 17939585STim.Szeto@Sun.COM (void) stmfFreeLuResource(hdl); 17949585STim.Szeto@Sun.COM return (ret); 17959585STim.Szeto@Sun.COM } 17969585STim.Szeto@Sun.COM 17979585STim.Szeto@Sun.COM static int 17989585STim.Szeto@Sun.COM validateModifyDiskProp(uint32_t prop) 17999585STim.Szeto@Sun.COM { 18009585STim.Szeto@Sun.COM switch (prop) { 18019585STim.Szeto@Sun.COM case STMF_LU_PROP_ALIAS: 18029585STim.Szeto@Sun.COM case STMF_LU_PROP_SIZE: 180310113SNattuvetty.Bhavyan@Sun.COM case STMF_LU_PROP_MGMT_URL: 18049585STim.Szeto@Sun.COM case STMF_LU_PROP_WRITE_PROTECT: 18059585STim.Szeto@Sun.COM case STMF_LU_PROP_WRITE_CACHE_DISABLE: 18069585STim.Szeto@Sun.COM return (STMF_STATUS_SUCCESS); 18079585STim.Szeto@Sun.COM break; 18089585STim.Szeto@Sun.COM default: 18099585STim.Szeto@Sun.COM return (STMF_STATUS_ERROR); 18109585STim.Szeto@Sun.COM break; 18119585STim.Szeto@Sun.COM } 18129585STim.Szeto@Sun.COM } 18139585STim.Szeto@Sun.COM 18149585STim.Szeto@Sun.COM static int 18159585STim.Szeto@Sun.COM modifyDiskLu(diskResource *disk, stmfGuid *luGuid, const char *fname) 18169585STim.Szeto@Sun.COM { 18179585STim.Szeto@Sun.COM int ret = STMF_STATUS_SUCCESS; 18189585STim.Szeto@Sun.COM int luAliasLen = 0; 181910113SNattuvetty.Bhavyan@Sun.COM int luMgmtUrlLen = 0; 18209585STim.Szeto@Sun.COM int mluBufSize = 0; 18219585STim.Szeto@Sun.COM int bufOffset = 0; 18229585STim.Szeto@Sun.COM int fd = 0; 18239585STim.Szeto@Sun.COM int ioctlRet; 18249585STim.Szeto@Sun.COM int savedErrno; 18259585STim.Szeto@Sun.COM int fnameSize = 0; 18269585STim.Szeto@Sun.COM stmf_iocdata_t sbdIoctl = {0}; 18279585STim.Szeto@Sun.COM 18289585STim.Szeto@Sun.COM sbd_modify_lu_t *sbdLu = NULL; 18299585STim.Szeto@Sun.COM 18309585STim.Szeto@Sun.COM if (luGuid == NULL && fname == NULL) { 18319585STim.Szeto@Sun.COM return (STMF_ERROR_INVALID_ARG); 18329585STim.Szeto@Sun.COM } 18339585STim.Szeto@Sun.COM 18349585STim.Szeto@Sun.COM if (fname) { 18359585STim.Szeto@Sun.COM fnameSize = strlen(fname) + 1; 18369585STim.Szeto@Sun.COM mluBufSize += fnameSize; 18379585STim.Szeto@Sun.COM } 18389585STim.Szeto@Sun.COM 18399585STim.Szeto@Sun.COM /* 18409585STim.Szeto@Sun.COM * Open control node for sbd 18419585STim.Szeto@Sun.COM */ 18429585STim.Szeto@Sun.COM if ((ret = openSbd(OPEN_SBD, &fd)) != STMF_STATUS_SUCCESS) 18439585STim.Szeto@Sun.COM return (ret); 18449585STim.Szeto@Sun.COM 18459585STim.Szeto@Sun.COM if (disk->luAliasValid) { 18469585STim.Szeto@Sun.COM luAliasLen = strlen(disk->luAlias); 18479585STim.Szeto@Sun.COM mluBufSize += luAliasLen + 1; 18489585STim.Szeto@Sun.COM } 18499585STim.Szeto@Sun.COM 185010113SNattuvetty.Bhavyan@Sun.COM if (disk->luMgmtUrlValid) { 185110113SNattuvetty.Bhavyan@Sun.COM luMgmtUrlLen = strlen(disk->luMgmtUrl); 185210113SNattuvetty.Bhavyan@Sun.COM mluBufSize += luMgmtUrlLen + 1; 185310113SNattuvetty.Bhavyan@Sun.COM } 185410113SNattuvetty.Bhavyan@Sun.COM 18559585STim.Szeto@Sun.COM /* 18569585STim.Szeto@Sun.COM * 8 is the size of the buffer set aside for 18579585STim.Szeto@Sun.COM * concatenation of variable length fields 18589585STim.Szeto@Sun.COM */ 18599585STim.Szeto@Sun.COM sbdLu = (sbd_modify_lu_t *)calloc(1, 18609585STim.Szeto@Sun.COM sizeof (sbd_modify_lu_t) + mluBufSize - 8 + fnameSize); 18619585STim.Szeto@Sun.COM if (sbdLu == NULL) { 18629585STim.Szeto@Sun.COM (void) close(fd); 18639585STim.Szeto@Sun.COM return (STMF_ERROR_NOMEM); 18649585STim.Szeto@Sun.COM } 18659585STim.Szeto@Sun.COM 18669585STim.Szeto@Sun.COM sbdLu->mlu_struct_size = sizeof (sbd_modify_lu_t) + 18679585STim.Szeto@Sun.COM mluBufSize - 8 + fnameSize; 18689585STim.Szeto@Sun.COM 18699585STim.Szeto@Sun.COM if (disk->luAliasValid) { 18709585STim.Szeto@Sun.COM sbdLu->mlu_alias_valid = 1; 18719585STim.Szeto@Sun.COM sbdLu->mlu_alias_off = bufOffset; 18729585STim.Szeto@Sun.COM bcopy(disk->luAlias, &(sbdLu->mlu_buf[bufOffset]), 18739585STim.Szeto@Sun.COM luAliasLen + 1); 18749585STim.Szeto@Sun.COM bufOffset += luAliasLen + 1; 18759585STim.Szeto@Sun.COM } 18769585STim.Szeto@Sun.COM 187710113SNattuvetty.Bhavyan@Sun.COM if (disk->luMgmtUrlValid) { 187810113SNattuvetty.Bhavyan@Sun.COM sbdLu->mlu_mgmt_url_valid = 1; 187910113SNattuvetty.Bhavyan@Sun.COM sbdLu->mlu_mgmt_url_off = bufOffset; 188010113SNattuvetty.Bhavyan@Sun.COM bcopy(disk->luMgmtUrl, &(sbdLu->mlu_buf[bufOffset]), 188110113SNattuvetty.Bhavyan@Sun.COM luMgmtUrlLen + 1); 188210113SNattuvetty.Bhavyan@Sun.COM bufOffset += luMgmtUrlLen + 1; 188310113SNattuvetty.Bhavyan@Sun.COM } 188410113SNattuvetty.Bhavyan@Sun.COM 18859585STim.Szeto@Sun.COM if (disk->luSizeValid) { 18869585STim.Szeto@Sun.COM sbdLu->mlu_lu_size_valid = 1; 18879585STim.Szeto@Sun.COM sbdLu->mlu_lu_size = disk->luSize; 18889585STim.Szeto@Sun.COM } 18899585STim.Szeto@Sun.COM 18909585STim.Szeto@Sun.COM if (disk->writeProtectEnableValid) { 18919585STim.Szeto@Sun.COM sbdLu->mlu_write_protected_valid = 1; 18929585STim.Szeto@Sun.COM if (disk->writeProtectEnable) { 18939585STim.Szeto@Sun.COM sbdLu->mlu_write_protected = 1; 18949585STim.Szeto@Sun.COM } 18959585STim.Szeto@Sun.COM } 18969585STim.Szeto@Sun.COM 18979585STim.Szeto@Sun.COM if (disk->writebackCacheDisableValid) { 18989585STim.Szeto@Sun.COM sbdLu->mlu_writeback_cache_disable_valid = 1; 18999585STim.Szeto@Sun.COM if (disk->writebackCacheDisable) { 19009585STim.Szeto@Sun.COM sbdLu->mlu_writeback_cache_disable = 1; 19019585STim.Szeto@Sun.COM } 19029585STim.Szeto@Sun.COM } 19039585STim.Szeto@Sun.COM 19049585STim.Szeto@Sun.COM if (luGuid) { 19059585STim.Szeto@Sun.COM bcopy(luGuid, sbdLu->mlu_input_guid, sizeof (stmfGuid)); 19069585STim.Szeto@Sun.COM sbdLu->mlu_by_guid = 1; 19079585STim.Szeto@Sun.COM } else { 19089585STim.Szeto@Sun.COM sbdLu->mlu_fname_off = bufOffset; 19099585STim.Szeto@Sun.COM bcopy(fname, &(sbdLu->mlu_buf[bufOffset]), fnameSize + 1); 19109585STim.Szeto@Sun.COM sbdLu->mlu_by_fname = 1; 19119585STim.Szeto@Sun.COM } 19129585STim.Szeto@Sun.COM 19139585STim.Szeto@Sun.COM sbdIoctl.stmf_version = STMF_VERSION_1; 19149585STim.Szeto@Sun.COM sbdIoctl.stmf_ibuf_size = sbdLu->mlu_struct_size; 19159585STim.Szeto@Sun.COM sbdIoctl.stmf_ibuf = (uint64_t)(unsigned long)sbdLu; 19169585STim.Szeto@Sun.COM 19179585STim.Szeto@Sun.COM ioctlRet = ioctl(fd, SBD_IOCTL_MODIFY_LU, &sbdIoctl); 19189585STim.Szeto@Sun.COM if (ioctlRet != 0) { 19199585STim.Szeto@Sun.COM savedErrno = errno; 19209585STim.Szeto@Sun.COM switch (savedErrno) { 19219585STim.Szeto@Sun.COM case EBUSY: 19229585STim.Szeto@Sun.COM ret = STMF_ERROR_BUSY; 19239585STim.Szeto@Sun.COM break; 19249585STim.Szeto@Sun.COM case EPERM: 19259585STim.Szeto@Sun.COM case EACCES: 19269585STim.Szeto@Sun.COM ret = STMF_ERROR_PERM; 19279585STim.Szeto@Sun.COM break; 19289585STim.Szeto@Sun.COM default: 19299585STim.Szeto@Sun.COM diskError(sbdIoctl.stmf_error, &ret); 19309585STim.Szeto@Sun.COM if (ret == STMF_STATUS_ERROR) { 19319585STim.Szeto@Sun.COM syslog(LOG_DEBUG, 19329585STim.Szeto@Sun.COM "modifyDiskLu:ioctl " 19339585STim.Szeto@Sun.COM "error(%d) (%d) (%d)", ioctlRet, 19349585STim.Szeto@Sun.COM sbdIoctl.stmf_error, savedErrno); 19359585STim.Szeto@Sun.COM } 19369585STim.Szeto@Sun.COM break; 19379585STim.Szeto@Sun.COM } 19389585STim.Szeto@Sun.COM } 19399585STim.Szeto@Sun.COM 19409585STim.Szeto@Sun.COM if (ret != STMF_STATUS_SUCCESS) { 19419585STim.Szeto@Sun.COM goto done; 19429585STim.Szeto@Sun.COM } 19439585STim.Szeto@Sun.COM 19449585STim.Szeto@Sun.COM done: 19459585STim.Szeto@Sun.COM free(sbdLu); 19469585STim.Szeto@Sun.COM (void) close(fd); 19479585STim.Szeto@Sun.COM return (ret); 19489585STim.Szeto@Sun.COM } 19499585STim.Szeto@Sun.COM 19509585STim.Szeto@Sun.COM /* 19519585STim.Szeto@Sun.COM * removeGuidFromDiskStore 19529585STim.Szeto@Sun.COM * 19539585STim.Szeto@Sun.COM * Purpose: delete a logical unit from the sbd provider data 19549585STim.Szeto@Sun.COM */ 19559585STim.Szeto@Sun.COM static int 19569585STim.Szeto@Sun.COM removeGuidFromDiskStore(stmfGuid *guid) 19579585STim.Szeto@Sun.COM { 19589585STim.Szeto@Sun.COM return (persistDiskGuid(guid, NULL, B_FALSE)); 19599585STim.Szeto@Sun.COM } 19609585STim.Szeto@Sun.COM 19619585STim.Szeto@Sun.COM 19629585STim.Szeto@Sun.COM /* 19639585STim.Szeto@Sun.COM * addGuidToDiskStore 19649585STim.Szeto@Sun.COM * 19659585STim.Szeto@Sun.COM * Purpose: add a logical unit to the sbd provider data 19669585STim.Szeto@Sun.COM */ 19679585STim.Szeto@Sun.COM static int 19689585STim.Szeto@Sun.COM addGuidToDiskStore(stmfGuid *guid, char *filename) 19699585STim.Szeto@Sun.COM { 19709585STim.Szeto@Sun.COM return (persistDiskGuid(guid, filename, B_TRUE)); 19719585STim.Szeto@Sun.COM } 19729585STim.Szeto@Sun.COM 19739585STim.Szeto@Sun.COM 19749585STim.Szeto@Sun.COM /* 19759585STim.Szeto@Sun.COM * persistDiskGuid 19769585STim.Szeto@Sun.COM * 19779585STim.Szeto@Sun.COM * Purpose: Persist or unpersist a guid for the sbd provider data 19789585STim.Szeto@Sun.COM * 19799585STim.Szeto@Sun.COM */ 19809585STim.Szeto@Sun.COM static int 19819585STim.Szeto@Sun.COM persistDiskGuid(stmfGuid *guid, char *filename, boolean_t persist) 19829585STim.Szeto@Sun.COM { 19839585STim.Szeto@Sun.COM char guidAsciiBuf[LU_ASCII_GUID_SIZE + 1] = {0}; 19849585STim.Szeto@Sun.COM nvlist_t *nvl = NULL; 19859585STim.Szeto@Sun.COM 19869585STim.Szeto@Sun.COM uint64_t setToken; 19879585STim.Szeto@Sun.COM boolean_t retryGetProviderData = B_FALSE; 19889585STim.Szeto@Sun.COM boolean_t newData = B_FALSE; 19899585STim.Szeto@Sun.COM int ret = STMF_STATUS_SUCCESS; 19909585STim.Szeto@Sun.COM int retryCnt = 0; 19919585STim.Szeto@Sun.COM int stmfRet; 19929585STim.Szeto@Sun.COM 19939585STim.Szeto@Sun.COM /* if we're persisting a guid, there must be a filename */ 19949585STim.Szeto@Sun.COM if (persist && !filename) { 19959585STim.Szeto@Sun.COM return (1); 19969585STim.Szeto@Sun.COM } 19979585STim.Szeto@Sun.COM 19989585STim.Szeto@Sun.COM /* guid is stored in lowercase ascii hex */ 19999585STim.Szeto@Sun.COM (void) snprintf(guidAsciiBuf, sizeof (guidAsciiBuf), 20009585STim.Szeto@Sun.COM "%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x" 20019585STim.Szeto@Sun.COM "%02x%02x%02x%02x%02x%02x", 20029585STim.Szeto@Sun.COM guid->guid[0], guid->guid[1], guid->guid[2], guid->guid[3], 20039585STim.Szeto@Sun.COM guid->guid[4], guid->guid[5], guid->guid[6], guid->guid[7], 20049585STim.Szeto@Sun.COM guid->guid[8], guid->guid[9], guid->guid[10], guid->guid[11], 20059585STim.Szeto@Sun.COM guid->guid[12], guid->guid[13], guid->guid[14], guid->guid[15]); 20069585STim.Szeto@Sun.COM 20079585STim.Szeto@Sun.COM 20089585STim.Szeto@Sun.COM do { 20099585STim.Szeto@Sun.COM retryGetProviderData = B_FALSE; 20109585STim.Szeto@Sun.COM stmfRet = stmfGetProviderDataProt("sbd", &nvl, 20119585STim.Szeto@Sun.COM STMF_LU_PROVIDER_TYPE, &setToken); 20129585STim.Szeto@Sun.COM if (stmfRet != STMF_STATUS_SUCCESS) { 20139585STim.Szeto@Sun.COM if (persist && stmfRet == STMF_ERROR_NOT_FOUND) { 20149585STim.Szeto@Sun.COM ret = nvlist_alloc(&nvl, NV_UNIQUE_NAME, 0); 20159585STim.Szeto@Sun.COM if (ret != 0) { 20169585STim.Szeto@Sun.COM syslog(LOG_DEBUG, 20179585STim.Szeto@Sun.COM "unpersistGuid:nvlist_alloc(%d)", 20189585STim.Szeto@Sun.COM ret); 20199585STim.Szeto@Sun.COM ret = STMF_STATUS_ERROR; 20209585STim.Szeto@Sun.COM goto done; 20219585STim.Szeto@Sun.COM } 20229585STim.Szeto@Sun.COM newData = B_TRUE; 20239585STim.Szeto@Sun.COM } else { 2024*10725SJohn.Forte@Sun.COM /* 2025*10725SJohn.Forte@Sun.COM * if we're persisting the data, it's 2026*10725SJohn.Forte@Sun.COM * an error. Otherwise, just return 2027*10725SJohn.Forte@Sun.COM */ 2028*10725SJohn.Forte@Sun.COM if (persist) { 2029*10725SJohn.Forte@Sun.COM ret = stmfRet; 2030*10725SJohn.Forte@Sun.COM } 20319585STim.Szeto@Sun.COM goto done; 20329585STim.Szeto@Sun.COM } 20339585STim.Szeto@Sun.COM } 20349585STim.Szeto@Sun.COM if (persist) { 20359585STim.Szeto@Sun.COM ret = nvlist_add_string(nvl, guidAsciiBuf, filename); 20369585STim.Szeto@Sun.COM } else { 20379585STim.Szeto@Sun.COM ret = nvlist_remove(nvl, guidAsciiBuf, 20389585STim.Szeto@Sun.COM DATA_TYPE_STRING); 20399585STim.Szeto@Sun.COM if (ret == ENOENT) { 20409585STim.Szeto@Sun.COM ret = 0; 20419585STim.Szeto@Sun.COM } 20429585STim.Szeto@Sun.COM } 20439585STim.Szeto@Sun.COM if (ret == 0) { 20449585STim.Szeto@Sun.COM if (newData) { 20459585STim.Szeto@Sun.COM stmfRet = stmfSetProviderDataProt("sbd", nvl, 20469585STim.Szeto@Sun.COM STMF_LU_PROVIDER_TYPE, NULL); 20479585STim.Szeto@Sun.COM } else { 20489585STim.Szeto@Sun.COM stmfRet = stmfSetProviderDataProt("sbd", nvl, 20499585STim.Szeto@Sun.COM STMF_LU_PROVIDER_TYPE, &setToken); 20509585STim.Szeto@Sun.COM } 20519585STim.Szeto@Sun.COM if (stmfRet != STMF_STATUS_SUCCESS) { 20529585STim.Szeto@Sun.COM if (stmfRet == STMF_ERROR_BUSY) { 20539585STim.Szeto@Sun.COM /* get/set failed, try again */ 20549585STim.Szeto@Sun.COM retryGetProviderData = B_TRUE; 20559585STim.Szeto@Sun.COM if (retryCnt++ > MAX_PROVIDER_RETRY) { 20569585STim.Szeto@Sun.COM ret = stmfRet; 20579585STim.Szeto@Sun.COM break; 20589585STim.Szeto@Sun.COM } 20599585STim.Szeto@Sun.COM continue; 20609585STim.Szeto@Sun.COM } else if (stmfRet == 20619585STim.Szeto@Sun.COM STMF_ERROR_PROV_DATA_STALE) { 20629585STim.Szeto@Sun.COM /* update failed, try again */ 20639585STim.Szeto@Sun.COM nvlist_free(nvl); 20649585STim.Szeto@Sun.COM nvl = NULL; 20659585STim.Szeto@Sun.COM retryGetProviderData = B_TRUE; 20669585STim.Szeto@Sun.COM if (retryCnt++ > MAX_PROVIDER_RETRY) { 20679585STim.Szeto@Sun.COM ret = stmfRet; 20689585STim.Szeto@Sun.COM break; 20699585STim.Szeto@Sun.COM } 20709585STim.Szeto@Sun.COM continue; 20719585STim.Szeto@Sun.COM } else { 20729585STim.Szeto@Sun.COM syslog(LOG_DEBUG, 20739585STim.Szeto@Sun.COM "unpersistGuid:error(%x)", stmfRet); 20749585STim.Szeto@Sun.COM ret = stmfRet; 20759585STim.Szeto@Sun.COM } 20769585STim.Szeto@Sun.COM break; 20779585STim.Szeto@Sun.COM } 20789585STim.Szeto@Sun.COM } else { 20799585STim.Szeto@Sun.COM syslog(LOG_DEBUG, 20809585STim.Szeto@Sun.COM "unpersistGuid:error nvlist_add/remove(%d)", 20819585STim.Szeto@Sun.COM ret); 20829585STim.Szeto@Sun.COM ret = STMF_STATUS_ERROR; 20839585STim.Szeto@Sun.COM } 20849585STim.Szeto@Sun.COM } while (retryGetProviderData); 20859585STim.Szeto@Sun.COM 20869585STim.Szeto@Sun.COM done: 20879585STim.Szeto@Sun.COM nvlist_free(nvl); 20889585STim.Szeto@Sun.COM return (ret); 20899585STim.Szeto@Sun.COM } 20909585STim.Szeto@Sun.COM 20919585STim.Szeto@Sun.COM 20929585STim.Szeto@Sun.COM /* 20939585STim.Szeto@Sun.COM * stmfGetLuProp 20949585STim.Szeto@Sun.COM * 20959585STim.Szeto@Sun.COM * Purpose: Get current value for a resource property 20969585STim.Szeto@Sun.COM * 20979585STim.Szeto@Sun.COM * hdl - luResource from a previous call to stmfCreateLuResource 20989585STim.Szeto@Sun.COM * 20999585STim.Szeto@Sun.COM * resourceProp - a valid resource property type 21009585STim.Szeto@Sun.COM * 21019585STim.Szeto@Sun.COM * propVal - void pointer to a pointer of the value to be retrieved 21029585STim.Szeto@Sun.COM */ 21039585STim.Szeto@Sun.COM int 21049585STim.Szeto@Sun.COM stmfGetLuProp(luResource hdl, uint32_t prop, char *propVal, size_t *propLen) 21059585STim.Szeto@Sun.COM { 21069585STim.Szeto@Sun.COM int ret = STMF_STATUS_SUCCESS; 21079585STim.Szeto@Sun.COM luResourceImpl *luPropsHdl = hdl; 21089585STim.Szeto@Sun.COM if (hdl == NULL || propLen == NULL || propVal == NULL) { 21099585STim.Szeto@Sun.COM return (STMF_ERROR_INVALID_ARG); 21109585STim.Szeto@Sun.COM } 21119585STim.Szeto@Sun.COM 21129585STim.Szeto@Sun.COM if (luPropsHdl->type == STMF_DISK) { 21139585STim.Szeto@Sun.COM ret = getDiskProp(luPropsHdl, prop, propVal, propLen); 21149585STim.Szeto@Sun.COM } else { 21159585STim.Szeto@Sun.COM return (STMF_ERROR_INVALID_ARG); 21169585STim.Szeto@Sun.COM } 21179585STim.Szeto@Sun.COM 21189585STim.Szeto@Sun.COM return (ret); 21199585STim.Szeto@Sun.COM } 21209585STim.Szeto@Sun.COM 21219585STim.Szeto@Sun.COM /* 21229585STim.Szeto@Sun.COM * stmfGetLuResource 21239585STim.Szeto@Sun.COM * 21249585STim.Szeto@Sun.COM * Purpose: Get a logical unit resource handle for a given logical unit. 21259585STim.Szeto@Sun.COM * 21269585STim.Szeto@Sun.COM * hdl - pointer to luResource 21279585STim.Szeto@Sun.COM */ 21289585STim.Szeto@Sun.COM int 21299585STim.Szeto@Sun.COM stmfGetLuResource(stmfGuid *luGuid, luResource *hdl) 21309585STim.Szeto@Sun.COM { 21319585STim.Szeto@Sun.COM int ret = STMF_STATUS_SUCCESS; 21329585STim.Szeto@Sun.COM stmfLogicalUnitProperties luProps; 21339585STim.Szeto@Sun.COM 21349585STim.Szeto@Sun.COM 21359585STim.Szeto@Sun.COM /* Check logical unit provider name to call correct dtype function */ 21369585STim.Szeto@Sun.COM if ((ret = stmfGetLogicalUnitProperties(luGuid, &luProps)) 21379585STim.Szeto@Sun.COM != STMF_STATUS_SUCCESS) { 21389585STim.Szeto@Sun.COM return (ret); 21399585STim.Szeto@Sun.COM } else { 21409585STim.Szeto@Sun.COM if (strcmp(luProps.providerName, "sbd") == 0) { 21419585STim.Szeto@Sun.COM ret = getDiskAllProps(luGuid, hdl); 21429585STim.Szeto@Sun.COM } else if (luProps.status == STMF_LOGICAL_UNIT_UNREGISTERED) { 21439585STim.Szeto@Sun.COM return (STMF_ERROR_NOT_FOUND); 21449585STim.Szeto@Sun.COM } else { 21459585STim.Szeto@Sun.COM return (STMF_ERROR_INVALID_ARG); 21469585STim.Szeto@Sun.COM } 21479585STim.Szeto@Sun.COM } 21489585STim.Szeto@Sun.COM 21499585STim.Szeto@Sun.COM return (ret); 21509585STim.Szeto@Sun.COM } 21519585STim.Szeto@Sun.COM 21529585STim.Szeto@Sun.COM /* 21539585STim.Szeto@Sun.COM * getDiskAllProps 21549585STim.Szeto@Sun.COM * 21559585STim.Szeto@Sun.COM * Purpose: load all disk properties from sbd driver 21569585STim.Szeto@Sun.COM * 21579585STim.Szeto@Sun.COM * luGuid - guid of disk device for which properties are to be retrieved 21589585STim.Szeto@Sun.COM * hdl - allocated luResource into which properties are to be copied 21599585STim.Szeto@Sun.COM * 21609585STim.Szeto@Sun.COM */ 21619585STim.Szeto@Sun.COM static int 21629585STim.Szeto@Sun.COM getDiskAllProps(stmfGuid *luGuid, luResource *hdl) 21639585STim.Szeto@Sun.COM { 21649585STim.Szeto@Sun.COM int ret = STMF_STATUS_SUCCESS; 21659585STim.Szeto@Sun.COM int fd; 21669585STim.Szeto@Sun.COM sbd_lu_props_t *sbdProps; 21679585STim.Szeto@Sun.COM int ioctlRet; 21689585STim.Szeto@Sun.COM int savedErrno; 21699585STim.Szeto@Sun.COM int sbdPropsSize = sizeof (*sbdProps) + MAX_SBD_PROPS; 21709585STim.Szeto@Sun.COM stmf_iocdata_t sbdIoctl = {0}; 21719585STim.Szeto@Sun.COM 21729585STim.Szeto@Sun.COM /* 21739585STim.Szeto@Sun.COM * Open control node for sbd 21749585STim.Szeto@Sun.COM */ 21759585STim.Szeto@Sun.COM if ((ret = openSbd(OPEN_SBD, &fd)) != STMF_STATUS_SUCCESS) 21769585STim.Szeto@Sun.COM return (ret); 21779585STim.Szeto@Sun.COM 21789585STim.Szeto@Sun.COM 21799585STim.Szeto@Sun.COM *hdl = calloc(1, sizeof (luResourceImpl)); 21809585STim.Szeto@Sun.COM if (*hdl == NULL) { 21819585STim.Szeto@Sun.COM (void) close(fd); 21829585STim.Szeto@Sun.COM return (STMF_ERROR_NOMEM); 21839585STim.Szeto@Sun.COM } 21849585STim.Szeto@Sun.COM 21859585STim.Szeto@Sun.COM sbdProps = calloc(1, sbdPropsSize); 21869585STim.Szeto@Sun.COM if (sbdProps == NULL) { 21879585STim.Szeto@Sun.COM free(*hdl); 21889585STim.Szeto@Sun.COM (void) close(fd); 21899585STim.Szeto@Sun.COM return (STMF_ERROR_NOMEM); 21909585STim.Szeto@Sun.COM } 21919585STim.Szeto@Sun.COM 21929585STim.Szeto@Sun.COM ret = createDiskResource((luResourceImpl *)*hdl); 21939585STim.Szeto@Sun.COM if (ret != STMF_STATUS_SUCCESS) { 21949585STim.Szeto@Sun.COM free(*hdl); 2195*10725SJohn.Forte@Sun.COM free(sbdProps); 21969585STim.Szeto@Sun.COM (void) close(fd); 21979585STim.Szeto@Sun.COM return (ret); 21989585STim.Szeto@Sun.COM } 21999585STim.Szeto@Sun.COM 22009585STim.Szeto@Sun.COM sbdProps->slp_input_guid = 1; 22019585STim.Szeto@Sun.COM bcopy(luGuid, sbdProps->slp_guid, sizeof (sbdProps->slp_guid)); 22029585STim.Szeto@Sun.COM 22039585STim.Szeto@Sun.COM sbdIoctl.stmf_version = STMF_VERSION_1; 22049585STim.Szeto@Sun.COM sbdIoctl.stmf_ibuf_size = sbdPropsSize; 22059585STim.Szeto@Sun.COM sbdIoctl.stmf_ibuf = (uint64_t)(unsigned long)sbdProps; 22069585STim.Szeto@Sun.COM sbdIoctl.stmf_obuf_size = sbdPropsSize; 22079585STim.Szeto@Sun.COM sbdIoctl.stmf_obuf = (uint64_t)(unsigned long)sbdProps; 22089585STim.Szeto@Sun.COM ioctlRet = ioctl(fd, SBD_IOCTL_GET_LU_PROPS, &sbdIoctl); 22099585STim.Szeto@Sun.COM if (ioctlRet != 0) { 22109585STim.Szeto@Sun.COM savedErrno = errno; 22119585STim.Szeto@Sun.COM switch (savedErrno) { 22129585STim.Szeto@Sun.COM case EBUSY: 22139585STim.Szeto@Sun.COM ret = STMF_ERROR_BUSY; 22149585STim.Szeto@Sun.COM break; 22159585STim.Szeto@Sun.COM case EPERM: 22169585STim.Szeto@Sun.COM case EACCES: 22179585STim.Szeto@Sun.COM ret = STMF_ERROR_PERM; 22189585STim.Szeto@Sun.COM break; 22199585STim.Szeto@Sun.COM case ENOENT: 22209585STim.Szeto@Sun.COM ret = STMF_ERROR_NOT_FOUND; 22219585STim.Szeto@Sun.COM break; 22229585STim.Szeto@Sun.COM default: 22239585STim.Szeto@Sun.COM syslog(LOG_DEBUG, 22249585STim.Szeto@Sun.COM "getDiskAllProps:ioctl error(%d) (%d) (%d)", 22259585STim.Szeto@Sun.COM ioctlRet, sbdIoctl.stmf_error, savedErrno); 22269585STim.Szeto@Sun.COM ret = STMF_STATUS_ERROR; 22279585STim.Szeto@Sun.COM break; 22289585STim.Szeto@Sun.COM } 22299585STim.Szeto@Sun.COM } 22309585STim.Szeto@Sun.COM 22319585STim.Szeto@Sun.COM if (ret == STMF_STATUS_SUCCESS) { 22329585STim.Szeto@Sun.COM ret = loadDiskPropsFromDriver((luResourceImpl *)*hdl, sbdProps); 22339585STim.Szeto@Sun.COM } 22349585STim.Szeto@Sun.COM 2235*10725SJohn.Forte@Sun.COM free(sbdProps); 22369585STim.Szeto@Sun.COM (void) close(fd); 22379585STim.Szeto@Sun.COM return (ret); 22389585STim.Szeto@Sun.COM } 22399585STim.Szeto@Sun.COM 22409585STim.Szeto@Sun.COM /* 22419585STim.Szeto@Sun.COM * loadDiskPropsFromDriver 22429585STim.Szeto@Sun.COM * 22439585STim.Szeto@Sun.COM * Purpose: Retrieve all disk type properties from sbd driver 22449585STim.Szeto@Sun.COM * 22459585STim.Szeto@Sun.COM * hdl - Allocated luResourceImpl 22469585STim.Szeto@Sun.COM * sbdProps - sbd_lu_props_t structure returned from sbd driver 22479585STim.Szeto@Sun.COM * 22489585STim.Szeto@Sun.COM */ 22499585STim.Szeto@Sun.COM static int 22509585STim.Szeto@Sun.COM loadDiskPropsFromDriver(luResourceImpl *hdl, sbd_lu_props_t *sbdProps) 22519585STim.Szeto@Sun.COM { 22529585STim.Szeto@Sun.COM int ret = STMF_STATUS_SUCCESS; 22539585STim.Szeto@Sun.COM diskResource *diskLu = hdl->resource; 22549585STim.Szeto@Sun.COM /* copy guid */ 22559585STim.Szeto@Sun.COM diskLu->luGuidValid = B_TRUE; 22569585STim.Szeto@Sun.COM bcopy(sbdProps->slp_guid, diskLu->luGuid, sizeof (sbdProps->slp_guid)); 22579585STim.Szeto@Sun.COM 22589585STim.Szeto@Sun.COM if (sbdProps->slp_separate_meta && sbdProps->slp_meta_fname_valid) { 22599585STim.Szeto@Sun.COM diskLu->luMetaFileNameValid = B_TRUE; 22609585STim.Szeto@Sun.COM if (strlcpy(diskLu->luMetaFileName, 22619585STim.Szeto@Sun.COM (char *)&(sbdProps->slp_buf[sbdProps->slp_meta_fname_off]), 22629585STim.Szeto@Sun.COM sizeof (diskLu->luMetaFileName)) >= 22639585STim.Szeto@Sun.COM sizeof (diskLu->luMetaFileName)) { 22649585STim.Szeto@Sun.COM return (STMF_STATUS_ERROR); 22659585STim.Szeto@Sun.COM } 22669585STim.Szeto@Sun.COM } 22679585STim.Szeto@Sun.COM 22689585STim.Szeto@Sun.COM if (sbdProps->slp_data_fname_valid) { 22699585STim.Szeto@Sun.COM diskLu->luDataFileNameValid = B_TRUE; 22709585STim.Szeto@Sun.COM if (strlcpy(diskLu->luDataFileName, 22719585STim.Szeto@Sun.COM (char *)&(sbdProps->slp_buf[sbdProps->slp_data_fname_off]), 22729585STim.Szeto@Sun.COM sizeof (diskLu->luDataFileName)) >= 22739585STim.Szeto@Sun.COM sizeof (diskLu->luDataFileName)) { 22749585STim.Szeto@Sun.COM return (STMF_STATUS_ERROR); 22759585STim.Szeto@Sun.COM } 22769585STim.Szeto@Sun.COM } 22779585STim.Szeto@Sun.COM 22789585STim.Szeto@Sun.COM if (sbdProps->slp_serial_valid) { 22799585STim.Szeto@Sun.COM diskLu->serialNumValid = B_TRUE; 22809585STim.Szeto@Sun.COM bcopy(&(sbdProps->slp_buf[sbdProps->slp_serial_off]), 22819585STim.Szeto@Sun.COM diskLu->serialNum, sbdProps->slp_serial_size); 22829585STim.Szeto@Sun.COM } 22839585STim.Szeto@Sun.COM 228410113SNattuvetty.Bhavyan@Sun.COM if (sbdProps->slp_mgmt_url_valid) { 228510113SNattuvetty.Bhavyan@Sun.COM diskLu->luMgmtUrlValid = B_TRUE; 228610113SNattuvetty.Bhavyan@Sun.COM if (strlcpy(diskLu->luMgmtUrl, 228710113SNattuvetty.Bhavyan@Sun.COM (char *)&(sbdProps->slp_buf[sbdProps->slp_mgmt_url_off]), 228810113SNattuvetty.Bhavyan@Sun.COM sizeof (diskLu->luMgmtUrl)) >= 228910113SNattuvetty.Bhavyan@Sun.COM sizeof (diskLu->luMgmtUrl)) { 229010113SNattuvetty.Bhavyan@Sun.COM return (STMF_STATUS_ERROR); 229110113SNattuvetty.Bhavyan@Sun.COM } 229210113SNattuvetty.Bhavyan@Sun.COM } 229310113SNattuvetty.Bhavyan@Sun.COM 22949585STim.Szeto@Sun.COM if (sbdProps->slp_alias_valid) { 22959585STim.Szeto@Sun.COM diskLu->luAliasValid = B_TRUE; 22969585STim.Szeto@Sun.COM if (strlcpy(diskLu->luAlias, 22979585STim.Szeto@Sun.COM (char *)&(sbdProps->slp_buf[sbdProps->slp_alias_off]), 22989585STim.Szeto@Sun.COM sizeof (diskLu->luAlias)) >= 22999585STim.Szeto@Sun.COM sizeof (diskLu->luAlias)) { 23009585STim.Szeto@Sun.COM return (STMF_STATUS_ERROR); 23019585STim.Szeto@Sun.COM } 23029585STim.Szeto@Sun.COM } else { /* set alias to data filename if not set */ 23039585STim.Szeto@Sun.COM if (sbdProps->slp_data_fname_valid) { 23049585STim.Szeto@Sun.COM diskLu->luAliasValid = B_TRUE; 23059585STim.Szeto@Sun.COM if (strlcpy(diskLu->luAlias, 23069585STim.Szeto@Sun.COM (char *)&(sbdProps->slp_buf[ 23079585STim.Szeto@Sun.COM sbdProps->slp_data_fname_off]), 23089585STim.Szeto@Sun.COM sizeof (diskLu->luAlias)) >= 23099585STim.Szeto@Sun.COM sizeof (diskLu->luAlias)) { 23109585STim.Szeto@Sun.COM return (STMF_STATUS_ERROR); 23119585STim.Szeto@Sun.COM } 23129585STim.Szeto@Sun.COM } 23139585STim.Szeto@Sun.COM } 23149585STim.Szeto@Sun.COM 23159585STim.Szeto@Sun.COM diskLu->vidValid = B_TRUE; 23169585STim.Szeto@Sun.COM bcopy(sbdProps->slp_vid, diskLu->vid, sizeof (diskLu->vid)); 23179585STim.Szeto@Sun.COM 23189585STim.Szeto@Sun.COM diskLu->pidValid = B_TRUE; 23199585STim.Szeto@Sun.COM bcopy(sbdProps->slp_pid, diskLu->pid, sizeof (diskLu->pid)); 23209585STim.Szeto@Sun.COM 23219585STim.Szeto@Sun.COM diskLu->revValid = B_TRUE; 23229585STim.Szeto@Sun.COM bcopy(sbdProps->slp_rev, diskLu->rev, sizeof (diskLu->rev)); 23239585STim.Szeto@Sun.COM 23249585STim.Szeto@Sun.COM diskLu->writeProtectEnableValid = B_TRUE; 23259585STim.Szeto@Sun.COM if (sbdProps->slp_write_protected) { 23269585STim.Szeto@Sun.COM diskLu->writeProtectEnable = B_TRUE; 23279585STim.Szeto@Sun.COM } 23289585STim.Szeto@Sun.COM 23299585STim.Szeto@Sun.COM diskLu->writebackCacheDisableValid = B_TRUE; 23309585STim.Szeto@Sun.COM if (sbdProps->slp_writeback_cache_disable_cur) { 23319585STim.Szeto@Sun.COM diskLu->writebackCacheDisable = B_TRUE; 23329585STim.Szeto@Sun.COM } 23339585STim.Szeto@Sun.COM 23349585STim.Szeto@Sun.COM diskLu->blkSizeValid = B_TRUE; 23359585STim.Szeto@Sun.COM diskLu->blkSize = sbdProps->slp_blksize; 23369585STim.Szeto@Sun.COM 23379585STim.Szeto@Sun.COM diskLu->luSizeValid = B_TRUE; 23389585STim.Szeto@Sun.COM diskLu->luSize = sbdProps->slp_lu_size; 23399585STim.Szeto@Sun.COM 2340*10725SJohn.Forte@Sun.COM diskLu->accessState = sbdProps->slp_access_state; 2341*10725SJohn.Forte@Sun.COM 23429585STim.Szeto@Sun.COM return (ret); 23439585STim.Szeto@Sun.COM } 23449585STim.Szeto@Sun.COM 23459585STim.Szeto@Sun.COM 23469585STim.Szeto@Sun.COM /* 23479585STim.Szeto@Sun.COM * stmfSetLuProp 23489585STim.Szeto@Sun.COM * 23499585STim.Szeto@Sun.COM * Purpose: set a property on an luResource 23509585STim.Szeto@Sun.COM * 23519585STim.Szeto@Sun.COM * hdl - allocated luResource 23529585STim.Szeto@Sun.COM * prop - property identifier 23539585STim.Szeto@Sun.COM * propVal - property value to be set 23549585STim.Szeto@Sun.COM */ 23559585STim.Szeto@Sun.COM int 23569585STim.Szeto@Sun.COM stmfSetLuProp(luResource hdl, uint32_t prop, const char *propVal) 23579585STim.Szeto@Sun.COM { 23589585STim.Szeto@Sun.COM int ret = STMF_STATUS_SUCCESS; 23599585STim.Szeto@Sun.COM luResourceImpl *luPropsHdl = hdl; 23609585STim.Szeto@Sun.COM if (hdl == NULL) { 23619585STim.Szeto@Sun.COM return (STMF_ERROR_INVALID_ARG); 23629585STim.Szeto@Sun.COM } 23639585STim.Szeto@Sun.COM 23649585STim.Szeto@Sun.COM if (luPropsHdl->type == STMF_DISK) { 23659585STim.Szeto@Sun.COM ret = setDiskProp(luPropsHdl, prop, propVal); 23669585STim.Szeto@Sun.COM } else { 23679585STim.Szeto@Sun.COM return (STMF_ERROR_INVALID_ARG); 23689585STim.Szeto@Sun.COM } 23699585STim.Szeto@Sun.COM 23709585STim.Szeto@Sun.COM return (ret); 23719585STim.Szeto@Sun.COM } 23729585STim.Szeto@Sun.COM 23739585STim.Szeto@Sun.COM /* 23749585STim.Szeto@Sun.COM * getDiskProp 23759585STim.Szeto@Sun.COM * 23769585STim.Szeto@Sun.COM * Purpose: retrieve a given property from a logical unit resource of type disk 23779585STim.Szeto@Sun.COM * 23789585STim.Szeto@Sun.COM * hdl - allocated luResourceImpl 23799585STim.Szeto@Sun.COM * prop - property identifier 23809585STim.Szeto@Sun.COM * propVal - pointer to character to contain the retrieved property value 23819585STim.Szeto@Sun.COM * propLen - On input this is the length of propVal. On failure, it contains the 23829585STim.Szeto@Sun.COM * number of bytes required for propVal 23839585STim.Szeto@Sun.COM */ 23849585STim.Szeto@Sun.COM static int 23859585STim.Szeto@Sun.COM getDiskProp(luResourceImpl *hdl, uint32_t prop, char *propVal, size_t *propLen) 23869585STim.Szeto@Sun.COM { 23879585STim.Szeto@Sun.COM int ret = STMF_STATUS_SUCCESS; 23889585STim.Szeto@Sun.COM diskResource *diskLu = hdl->resource; 2389*10725SJohn.Forte@Sun.COM char accessState[20]; 23909585STim.Szeto@Sun.COM size_t reqLen; 23919585STim.Szeto@Sun.COM 2392*10725SJohn.Forte@Sun.COM if (prop == STMF_LU_PROP_ACCESS_STATE) { 2393*10725SJohn.Forte@Sun.COM if (diskLu->accessState == SBD_LU_ACTIVE) { 2394*10725SJohn.Forte@Sun.COM (void) strlcpy(accessState, STMF_ACCESS_ACTIVE, 2395*10725SJohn.Forte@Sun.COM sizeof (accessState)); 2396*10725SJohn.Forte@Sun.COM } else if (diskLu->accessState == SBD_LU_TRANSITION_TO_ACTIVE) { 2397*10725SJohn.Forte@Sun.COM (void) strlcpy(accessState, 2398*10725SJohn.Forte@Sun.COM STMF_ACCESS_STANDBY_TO_ACTIVE, 2399*10725SJohn.Forte@Sun.COM sizeof (accessState)); 2400*10725SJohn.Forte@Sun.COM } else if (diskLu->accessState == SBD_LU_STANDBY) { 2401*10725SJohn.Forte@Sun.COM (void) strlcpy(accessState, STMF_ACCESS_STANDBY, 2402*10725SJohn.Forte@Sun.COM sizeof (accessState)); 2403*10725SJohn.Forte@Sun.COM } else if (diskLu->accessState == 2404*10725SJohn.Forte@Sun.COM SBD_LU_TRANSITION_TO_STANDBY) { 2405*10725SJohn.Forte@Sun.COM (void) strlcpy(accessState, 2406*10725SJohn.Forte@Sun.COM STMF_ACCESS_ACTIVE_TO_STANDBY, 2407*10725SJohn.Forte@Sun.COM sizeof (accessState)); 2408*10725SJohn.Forte@Sun.COM } 2409*10725SJohn.Forte@Sun.COM if ((reqLen = strlcpy(propVal, accessState, 2410*10725SJohn.Forte@Sun.COM *propLen)) >= *propLen) { 2411*10725SJohn.Forte@Sun.COM *propLen = reqLen + 1; 2412*10725SJohn.Forte@Sun.COM return (STMF_ERROR_INVALID_ARG); 2413*10725SJohn.Forte@Sun.COM } 2414*10725SJohn.Forte@Sun.COM return (0); 2415*10725SJohn.Forte@Sun.COM } 2416*10725SJohn.Forte@Sun.COM 2417*10725SJohn.Forte@Sun.COM if (diskLu->accessState != SBD_LU_ACTIVE) { 2418*10725SJohn.Forte@Sun.COM return (STMF_ERROR_NO_PROP_STANDBY); 2419*10725SJohn.Forte@Sun.COM } 2420*10725SJohn.Forte@Sun.COM 24219585STim.Szeto@Sun.COM switch (prop) { 24229585STim.Szeto@Sun.COM case STMF_LU_PROP_BLOCK_SIZE: 24239585STim.Szeto@Sun.COM if (diskLu->blkSizeValid == B_FALSE) { 24249585STim.Szeto@Sun.COM return (STMF_ERROR_NO_PROP); 24259585STim.Szeto@Sun.COM } 24269585STim.Szeto@Sun.COM reqLen = snprintf(propVal, *propLen, "%llu", 24279585STim.Szeto@Sun.COM (u_longlong_t)diskLu->blkSize); 24289585STim.Szeto@Sun.COM if (reqLen >= *propLen) { 24299585STim.Szeto@Sun.COM *propLen = reqLen + 1; 24309585STim.Szeto@Sun.COM return (STMF_ERROR_INVALID_ARG); 24319585STim.Szeto@Sun.COM } 24329585STim.Szeto@Sun.COM break; 24339585STim.Szeto@Sun.COM case STMF_LU_PROP_FILENAME: 24349585STim.Szeto@Sun.COM if (diskLu->luDataFileNameValid == B_FALSE) { 24359585STim.Szeto@Sun.COM return (STMF_ERROR_NO_PROP); 24369585STim.Szeto@Sun.COM } 24379585STim.Szeto@Sun.COM if ((reqLen = strlcpy(propVal, diskLu->luDataFileName, 24389585STim.Szeto@Sun.COM *propLen)) >= *propLen) { 24399585STim.Szeto@Sun.COM *propLen = reqLen + 1; 24409585STim.Szeto@Sun.COM return (STMF_ERROR_INVALID_ARG); 24419585STim.Szeto@Sun.COM } 24429585STim.Szeto@Sun.COM break; 24439585STim.Szeto@Sun.COM case STMF_LU_PROP_META_FILENAME: 24449585STim.Szeto@Sun.COM if (diskLu->luMetaFileNameValid == B_FALSE) { 24459585STim.Szeto@Sun.COM return (STMF_ERROR_NO_PROP); 24469585STim.Szeto@Sun.COM } 24479585STim.Szeto@Sun.COM if ((reqLen = strlcpy(propVal, diskLu->luMetaFileName, 24489585STim.Szeto@Sun.COM *propLen)) >= *propLen) { 24499585STim.Szeto@Sun.COM *propLen = reqLen + 1; 24509585STim.Szeto@Sun.COM return (STMF_ERROR_INVALID_ARG); 24519585STim.Szeto@Sun.COM } 24529585STim.Szeto@Sun.COM break; 245310113SNattuvetty.Bhavyan@Sun.COM case STMF_LU_PROP_MGMT_URL: 245410113SNattuvetty.Bhavyan@Sun.COM if (diskLu->luMgmtUrlValid == B_FALSE) { 245510113SNattuvetty.Bhavyan@Sun.COM return (STMF_ERROR_NO_PROP); 245610113SNattuvetty.Bhavyan@Sun.COM } 245710113SNattuvetty.Bhavyan@Sun.COM if ((reqLen = strlcpy(propVal, diskLu->luMgmtUrl, 245810113SNattuvetty.Bhavyan@Sun.COM *propLen)) >= *propLen) { 245910113SNattuvetty.Bhavyan@Sun.COM *propLen = reqLen + 1; 246010113SNattuvetty.Bhavyan@Sun.COM return (STMF_ERROR_INVALID_ARG); 246110113SNattuvetty.Bhavyan@Sun.COM } 246210113SNattuvetty.Bhavyan@Sun.COM break; 24639585STim.Szeto@Sun.COM case STMF_LU_PROP_GUID: 24649585STim.Szeto@Sun.COM if (diskLu->luGuidValid == B_FALSE) { 24659585STim.Szeto@Sun.COM return (STMF_ERROR_NO_PROP); 24669585STim.Szeto@Sun.COM } 24679585STim.Szeto@Sun.COM reqLen = snprintf(propVal, *propLen, 24689585STim.Szeto@Sun.COM "%02X%02X%02X%02X%02X%02X%02X%02X%02X%02X%02X%02X" 24699585STim.Szeto@Sun.COM "%02X%02X%02X%02X", 24709585STim.Szeto@Sun.COM diskLu->luGuid[0], diskLu->luGuid[1], 24719585STim.Szeto@Sun.COM diskLu->luGuid[2], diskLu->luGuid[3], 24729585STim.Szeto@Sun.COM diskLu->luGuid[4], diskLu->luGuid[5], 24739585STim.Szeto@Sun.COM diskLu->luGuid[6], diskLu->luGuid[7], 24749585STim.Szeto@Sun.COM diskLu->luGuid[8], diskLu->luGuid[9], 24759585STim.Szeto@Sun.COM diskLu->luGuid[10], diskLu->luGuid[11], 24769585STim.Szeto@Sun.COM diskLu->luGuid[12], diskLu->luGuid[13], 24779585STim.Szeto@Sun.COM diskLu->luGuid[14], diskLu->luGuid[15]); 24789585STim.Szeto@Sun.COM if (reqLen >= *propLen) { 24799585STim.Szeto@Sun.COM *propLen = reqLen + 1; 24809585STim.Szeto@Sun.COM return (STMF_ERROR_INVALID_ARG); 24819585STim.Szeto@Sun.COM } 24829585STim.Szeto@Sun.COM break; 24839585STim.Szeto@Sun.COM case STMF_LU_PROP_SERIAL_NUM: 24849585STim.Szeto@Sun.COM if (diskLu->serialNumValid == B_FALSE) { 24859585STim.Szeto@Sun.COM return (STMF_ERROR_NO_PROP); 24869585STim.Szeto@Sun.COM } 24879585STim.Szeto@Sun.COM if ((reqLen = strlcpy(propVal, diskLu->serialNum, 24889585STim.Szeto@Sun.COM *propLen)) >= *propLen) { 24899585STim.Szeto@Sun.COM *propLen = reqLen + 1; 24909585STim.Szeto@Sun.COM return (STMF_ERROR_INVALID_ARG); 24919585STim.Szeto@Sun.COM } 24929585STim.Szeto@Sun.COM break; 24939585STim.Szeto@Sun.COM case STMF_LU_PROP_SIZE: 24949585STim.Szeto@Sun.COM if (diskLu->luSizeValid == B_FALSE) { 24959585STim.Szeto@Sun.COM return (STMF_ERROR_NO_PROP); 24969585STim.Szeto@Sun.COM } 24979585STim.Szeto@Sun.COM (void) snprintf(propVal, *propLen, "%llu", 24989585STim.Szeto@Sun.COM (u_longlong_t)diskLu->luSize); 24999585STim.Szeto@Sun.COM break; 25009585STim.Szeto@Sun.COM case STMF_LU_PROP_ALIAS: 25019585STim.Szeto@Sun.COM if (diskLu->luAliasValid == B_FALSE) { 25029585STim.Szeto@Sun.COM return (STMF_ERROR_NO_PROP); 25039585STim.Szeto@Sun.COM } 25049585STim.Szeto@Sun.COM if ((reqLen = strlcpy(propVal, diskLu->luAlias, 25059585STim.Szeto@Sun.COM *propLen)) >= *propLen) { 25069585STim.Szeto@Sun.COM *propLen = reqLen + 1; 25079585STim.Szeto@Sun.COM return (STMF_ERROR_INVALID_ARG); 25089585STim.Szeto@Sun.COM } 25099585STim.Szeto@Sun.COM break; 25109585STim.Szeto@Sun.COM case STMF_LU_PROP_VID: 25119585STim.Szeto@Sun.COM if (diskLu->vidValid == B_FALSE) { 25129585STim.Szeto@Sun.COM return (STMF_ERROR_NO_PROP); 25139585STim.Szeto@Sun.COM } 25149585STim.Szeto@Sun.COM if (*propLen <= sizeof (diskLu->vid)) { 25159585STim.Szeto@Sun.COM return (STMF_ERROR_INVALID_ARG); 25169585STim.Szeto@Sun.COM } 25179585STim.Szeto@Sun.COM bcopy(diskLu->vid, propVal, sizeof (diskLu->vid)); 25189585STim.Szeto@Sun.COM propVal[sizeof (diskLu->vid)] = 0; 25199585STim.Szeto@Sun.COM break; 25209585STim.Szeto@Sun.COM case STMF_LU_PROP_PID: 25219585STim.Szeto@Sun.COM if (diskLu->pidValid == B_FALSE) { 25229585STim.Szeto@Sun.COM return (STMF_ERROR_NO_PROP); 25239585STim.Szeto@Sun.COM } 25249585STim.Szeto@Sun.COM if (*propLen <= sizeof (diskLu->pid)) { 25259585STim.Szeto@Sun.COM return (STMF_ERROR_INVALID_ARG); 25269585STim.Szeto@Sun.COM } 25279585STim.Szeto@Sun.COM bcopy(diskLu->pid, propVal, sizeof (diskLu->pid)); 25289585STim.Szeto@Sun.COM propVal[sizeof (diskLu->pid)] = 0; 25299585STim.Szeto@Sun.COM break; 25309585STim.Szeto@Sun.COM case STMF_LU_PROP_WRITE_PROTECT: 25319585STim.Szeto@Sun.COM if (diskLu->writeProtectEnableValid == B_FALSE) { 25329585STim.Szeto@Sun.COM return (STMF_ERROR_NO_PROP); 25339585STim.Szeto@Sun.COM } 25349585STim.Szeto@Sun.COM if (diskLu->writeProtectEnable) { 25359585STim.Szeto@Sun.COM if ((reqLen = strlcpy(propVal, "true", 25369585STim.Szeto@Sun.COM *propLen)) >= *propLen) { 25379585STim.Szeto@Sun.COM *propLen = reqLen + 1; 25389585STim.Szeto@Sun.COM return (STMF_ERROR_INVALID_ARG); 25399585STim.Szeto@Sun.COM } 25409585STim.Szeto@Sun.COM } else { 25419585STim.Szeto@Sun.COM if ((reqLen = strlcpy(propVal, "false", 25429585STim.Szeto@Sun.COM *propLen)) >= *propLen) { 25439585STim.Szeto@Sun.COM *propLen = reqLen + 1; 25449585STim.Szeto@Sun.COM return (STMF_ERROR_INVALID_ARG); 25459585STim.Szeto@Sun.COM } 25469585STim.Szeto@Sun.COM } 25479585STim.Szeto@Sun.COM break; 25489585STim.Szeto@Sun.COM case STMF_LU_PROP_WRITE_CACHE_DISABLE: 25499585STim.Szeto@Sun.COM if (diskLu->writebackCacheDisableValid == B_FALSE) { 25509585STim.Szeto@Sun.COM return (STMF_ERROR_NO_PROP); 25519585STim.Szeto@Sun.COM } 25529585STim.Szeto@Sun.COM if (diskLu->writebackCacheDisable) { 25539585STim.Szeto@Sun.COM if ((reqLen = strlcpy(propVal, "true", 25549585STim.Szeto@Sun.COM *propLen)) >= *propLen) { 25559585STim.Szeto@Sun.COM *propLen = reqLen + 1; 25569585STim.Szeto@Sun.COM return (STMF_ERROR_INVALID_ARG); 25579585STim.Szeto@Sun.COM } 25589585STim.Szeto@Sun.COM } else { 25599585STim.Szeto@Sun.COM if ((reqLen = strlcpy(propVal, "false", 25609585STim.Szeto@Sun.COM *propLen)) >= *propLen) { 25619585STim.Szeto@Sun.COM *propLen = reqLen + 1; 25629585STim.Szeto@Sun.COM return (STMF_ERROR_INVALID_ARG); 25639585STim.Szeto@Sun.COM } 25649585STim.Szeto@Sun.COM } 25659585STim.Szeto@Sun.COM break; 25669585STim.Szeto@Sun.COM default: 25679585STim.Szeto@Sun.COM ret = STMF_ERROR_NO_PROP; 25689585STim.Szeto@Sun.COM break; 25699585STim.Szeto@Sun.COM } 25709585STim.Szeto@Sun.COM 25719585STim.Szeto@Sun.COM return (ret); 25729585STim.Szeto@Sun.COM } 25739585STim.Szeto@Sun.COM 25749585STim.Szeto@Sun.COM /* 25759585STim.Szeto@Sun.COM * setDiskProp 25769585STim.Szeto@Sun.COM * 25779585STim.Szeto@Sun.COM * Purpose: set properties for resource of type disk 25789585STim.Szeto@Sun.COM * 25799585STim.Szeto@Sun.COM * hdl - allocated luResourceImpl 25809585STim.Szeto@Sun.COM * resourceProp - valid resource identifier 25819585STim.Szeto@Sun.COM * propVal - valid resource value 25829585STim.Szeto@Sun.COM */ 25839585STim.Szeto@Sun.COM static int 25849585STim.Szeto@Sun.COM setDiskProp(luResourceImpl *hdl, uint32_t resourceProp, const char *propVal) 25859585STim.Szeto@Sun.COM { 25869585STim.Szeto@Sun.COM int ret = STMF_STATUS_SUCCESS; 25879585STim.Szeto@Sun.COM int i; 25889585STim.Szeto@Sun.COM diskResource *diskLu = hdl->resource; 25899585STim.Szeto@Sun.COM unsigned long long numericProp = 0; 25909585STim.Szeto@Sun.COM char guidProp[LU_ASCII_GUID_SIZE + 1]; 25919585STim.Szeto@Sun.COM char ouiProp[OUI_ASCII_SIZE + 1]; 25929585STim.Szeto@Sun.COM unsigned int oui[OUI_SIZE]; 25939585STim.Szeto@Sun.COM unsigned int guid[LU_GUID_SIZE]; 25949585STim.Szeto@Sun.COM int propSize; 25959585STim.Szeto@Sun.COM 25969585STim.Szeto@Sun.COM 25979585STim.Szeto@Sun.COM if (propVal == NULL) { 25989585STim.Szeto@Sun.COM return (STMF_ERROR_INVALID_ARG); 25999585STim.Szeto@Sun.COM } 26009585STim.Szeto@Sun.COM 26019585STim.Szeto@Sun.COM switch (resourceProp) { 26029585STim.Szeto@Sun.COM case STMF_LU_PROP_ALIAS: 26039585STim.Szeto@Sun.COM if (strlcpy(diskLu->luAlias, propVal, 26049585STim.Szeto@Sun.COM sizeof (diskLu->luAlias)) >= 26059585STim.Szeto@Sun.COM sizeof (diskLu->luAlias)) { 26069585STim.Szeto@Sun.COM return (STMF_ERROR_INVALID_PROPSIZE); 26079585STim.Szeto@Sun.COM } 26089585STim.Szeto@Sun.COM diskLu->luAliasValid = B_TRUE; 26099585STim.Szeto@Sun.COM break; 26109585STim.Szeto@Sun.COM case STMF_LU_PROP_BLOCK_SIZE: 26119585STim.Szeto@Sun.COM (void) sscanf(propVal, "%llu", &numericProp); 26129585STim.Szeto@Sun.COM if (numericProp > UINT16_MAX) { 26139585STim.Szeto@Sun.COM return (STMF_ERROR_INVALID_PROPSIZE); 26149585STim.Szeto@Sun.COM } 26159585STim.Szeto@Sun.COM diskLu->blkSize = numericProp; 26169585STim.Szeto@Sun.COM diskLu->blkSizeValid = B_TRUE; 26179585STim.Szeto@Sun.COM break; 26189585STim.Szeto@Sun.COM case STMF_LU_PROP_COMPANY_ID: 26199585STim.Szeto@Sun.COM if ((strlcpy(ouiProp, propVal, sizeof (ouiProp))) >= 26209585STim.Szeto@Sun.COM sizeof (ouiProp)) { 26219585STim.Szeto@Sun.COM return (STMF_ERROR_INVALID_ARG); 26229585STim.Szeto@Sun.COM } 26239585STim.Szeto@Sun.COM if (checkHexUpper(ouiProp) != 0) { 26249585STim.Szeto@Sun.COM return (STMF_ERROR_INVALID_ARG); 26259585STim.Szeto@Sun.COM } 26269585STim.Szeto@Sun.COM (void) sscanf(ouiProp, "%2X%2X%2X", 26279585STim.Szeto@Sun.COM &oui[0], &oui[1], &oui[2]); 26289585STim.Szeto@Sun.COM 26299585STim.Szeto@Sun.COM diskLu->companyId = 0; 26309585STim.Szeto@Sun.COM diskLu->companyId += oui[0] << 16; 26319585STim.Szeto@Sun.COM diskLu->companyId += oui[1] << 8; 26329585STim.Szeto@Sun.COM diskLu->companyId += oui[2]; 26339585STim.Szeto@Sun.COM diskLu->companyIdValid = B_TRUE; 26349585STim.Szeto@Sun.COM break; 26359585STim.Szeto@Sun.COM case STMF_LU_PROP_GUID: 26369585STim.Szeto@Sun.COM if (strlen(propVal) != LU_ASCII_GUID_SIZE) { 26379585STim.Szeto@Sun.COM return (STMF_ERROR_INVALID_PROPSIZE); 26389585STim.Szeto@Sun.COM } 26399585STim.Szeto@Sun.COM 26409585STim.Szeto@Sun.COM if ((strlcpy(guidProp, propVal, sizeof (guidProp))) >= 26419585STim.Szeto@Sun.COM sizeof (guidProp)) { 26429585STim.Szeto@Sun.COM return (STMF_ERROR_INVALID_ARG); 26439585STim.Szeto@Sun.COM } 26449585STim.Szeto@Sun.COM 26459585STim.Szeto@Sun.COM if (checkHexUpper(guidProp) != 0) { 26469585STim.Szeto@Sun.COM return (STMF_ERROR_INVALID_ARG); 26479585STim.Szeto@Sun.COM } 26489585STim.Szeto@Sun.COM 26499585STim.Szeto@Sun.COM (void) sscanf(guidProp, 26509585STim.Szeto@Sun.COM "%2X%2X%2X%2X%2X%2X%2X%2X%2X%2X%2X%2X%2X%2X%2X%2X", 26519585STim.Szeto@Sun.COM &guid[0], &guid[1], &guid[2], &guid[3], &guid[4], 26529585STim.Szeto@Sun.COM &guid[5], &guid[6], &guid[7], &guid[8], &guid[9], 26539585STim.Szeto@Sun.COM &guid[10], &guid[11], &guid[12], &guid[13], 26549585STim.Szeto@Sun.COM &guid[14], &guid[15]); 26559585STim.Szeto@Sun.COM for (i = 0; i < sizeof (diskLu->luGuid); i++) { 26569585STim.Szeto@Sun.COM diskLu->luGuid[i] = guid[i]; 26579585STim.Szeto@Sun.COM } 26589585STim.Szeto@Sun.COM diskLu->luGuidValid = B_TRUE; 26599585STim.Szeto@Sun.COM break; 26609585STim.Szeto@Sun.COM case STMF_LU_PROP_FILENAME: 26619585STim.Szeto@Sun.COM if ((strlcpy(diskLu->luDataFileName, propVal, 26629585STim.Szeto@Sun.COM sizeof (diskLu->luDataFileName))) >= 26639585STim.Szeto@Sun.COM sizeof (diskLu->luDataFileName)) { 26649585STim.Szeto@Sun.COM return (STMF_ERROR_INVALID_PROPSIZE); 26659585STim.Szeto@Sun.COM } 26669585STim.Szeto@Sun.COM diskLu->luDataFileNameValid = B_TRUE; 26679585STim.Szeto@Sun.COM break; 26689585STim.Szeto@Sun.COM case STMF_LU_PROP_META_FILENAME: 26699585STim.Szeto@Sun.COM if ((strlcpy(diskLu->luMetaFileName, propVal, 26709585STim.Szeto@Sun.COM sizeof (diskLu->luMetaFileName))) >= 26719585STim.Szeto@Sun.COM sizeof (diskLu->luMetaFileName)) { 26729585STim.Szeto@Sun.COM return (STMF_ERROR_INVALID_PROPSIZE); 26739585STim.Szeto@Sun.COM } 26749585STim.Szeto@Sun.COM diskLu->luMetaFileNameValid = B_TRUE; 26759585STim.Szeto@Sun.COM break; 267610113SNattuvetty.Bhavyan@Sun.COM case STMF_LU_PROP_MGMT_URL: 267710113SNattuvetty.Bhavyan@Sun.COM if ((strlcpy(diskLu->luMgmtUrl, propVal, 267810113SNattuvetty.Bhavyan@Sun.COM sizeof (diskLu->luMgmtUrl))) >= 267910113SNattuvetty.Bhavyan@Sun.COM sizeof (diskLu->luMgmtUrl)) { 268010113SNattuvetty.Bhavyan@Sun.COM return (STMF_ERROR_INVALID_PROPSIZE); 268110113SNattuvetty.Bhavyan@Sun.COM } 268210113SNattuvetty.Bhavyan@Sun.COM diskLu->luMgmtUrlValid = B_TRUE; 268310113SNattuvetty.Bhavyan@Sun.COM break; 26849585STim.Szeto@Sun.COM case STMF_LU_PROP_PID: 26859585STim.Szeto@Sun.COM if ((propSize = strlen(propVal)) > 26869585STim.Szeto@Sun.COM sizeof (diskLu->pid)) { 26879585STim.Szeto@Sun.COM return (STMF_ERROR_INVALID_PROPSIZE); 26889585STim.Szeto@Sun.COM } 26899585STim.Szeto@Sun.COM (void) strncpy(diskLu->pid, propVal, propSize); 26909585STim.Szeto@Sun.COM diskLu->pidValid = B_TRUE; 26919585STim.Szeto@Sun.COM break; 26929585STim.Szeto@Sun.COM case STMF_LU_PROP_SERIAL_NUM: 26939585STim.Szeto@Sun.COM if ((propSize = strlen(propVal)) > 26949585STim.Szeto@Sun.COM (sizeof (diskLu->serialNum) - 1)) { 26959585STim.Szeto@Sun.COM return (STMF_ERROR_INVALID_PROPSIZE); 26969585STim.Szeto@Sun.COM } 26979585STim.Szeto@Sun.COM (void) strncpy(diskLu->serialNum, propVal, propSize); 26989585STim.Szeto@Sun.COM diskLu->serialNumValid = B_TRUE; 26999585STim.Szeto@Sun.COM break; 27009585STim.Szeto@Sun.COM case STMF_LU_PROP_SIZE: 27019585STim.Szeto@Sun.COM if ((niceStrToNum(propVal, &diskLu->luSize) != 0)) { 27029585STim.Szeto@Sun.COM return (STMF_ERROR_INVALID_ARG); 27039585STim.Szeto@Sun.COM } 27049585STim.Szeto@Sun.COM diskLu->luSizeValid = B_TRUE; 27059585STim.Szeto@Sun.COM break; 27069585STim.Szeto@Sun.COM case STMF_LU_PROP_VID: 27079585STim.Szeto@Sun.COM if ((propSize = strlen(propVal)) > 27089585STim.Szeto@Sun.COM sizeof (diskLu->vid)) { 27099585STim.Szeto@Sun.COM return (STMF_ERROR_INVALID_PROPSIZE); 27109585STim.Szeto@Sun.COM } 27119585STim.Szeto@Sun.COM (void) strncpy(diskLu->vid, propVal, propSize); 27129585STim.Szeto@Sun.COM diskLu->vidValid = B_TRUE; 27139585STim.Szeto@Sun.COM break; 27149585STim.Szeto@Sun.COM case STMF_LU_PROP_WRITE_PROTECT: 27159585STim.Szeto@Sun.COM if (strcasecmp(propVal, "TRUE") == 0) { 27169585STim.Szeto@Sun.COM diskLu->writeProtectEnable = B_TRUE; 27179585STim.Szeto@Sun.COM } else if (strcasecmp(propVal, "FALSE") == 0) { 27189585STim.Szeto@Sun.COM diskLu->writeProtectEnable = B_FALSE; 27199585STim.Szeto@Sun.COM } else { 27209585STim.Szeto@Sun.COM return (STMF_ERROR_INVALID_ARG); 27219585STim.Szeto@Sun.COM } 27229585STim.Szeto@Sun.COM diskLu->writeProtectEnableValid = B_TRUE; 27239585STim.Szeto@Sun.COM break; 27249585STim.Szeto@Sun.COM case STMF_LU_PROP_WRITE_CACHE_DISABLE: 27259585STim.Szeto@Sun.COM if (strcasecmp(propVal, "TRUE") == 0) { 27269585STim.Szeto@Sun.COM diskLu->writebackCacheDisable = B_TRUE; 27279585STim.Szeto@Sun.COM } else if (strcasecmp(propVal, "FALSE") == 0) { 27289585STim.Szeto@Sun.COM diskLu->writebackCacheDisable = B_FALSE; 27299585STim.Szeto@Sun.COM } else { 27309585STim.Szeto@Sun.COM return (STMF_ERROR_INVALID_ARG); 27319585STim.Szeto@Sun.COM } 27329585STim.Szeto@Sun.COM diskLu->writebackCacheDisableValid = B_TRUE; 27339585STim.Szeto@Sun.COM break; 2734*10725SJohn.Forte@Sun.COM case STMF_LU_PROP_ACCESS_STATE: 2735*10725SJohn.Forte@Sun.COM ret = STMF_ERROR_INVALID_PROP; 2736*10725SJohn.Forte@Sun.COM break; 27379585STim.Szeto@Sun.COM default: 27389585STim.Szeto@Sun.COM ret = STMF_ERROR_NO_PROP; 27399585STim.Szeto@Sun.COM break; 27409585STim.Szeto@Sun.COM } 27419585STim.Szeto@Sun.COM return (ret); 27429585STim.Szeto@Sun.COM } 27439585STim.Szeto@Sun.COM 27449585STim.Szeto@Sun.COM static int 27459585STim.Szeto@Sun.COM checkHexUpper(char *buf) 27469585STim.Szeto@Sun.COM { 27479585STim.Szeto@Sun.COM int i; 27489585STim.Szeto@Sun.COM 27499585STim.Szeto@Sun.COM for (i = 0; i < strlen(buf); i++) { 27509585STim.Szeto@Sun.COM if (isxdigit(buf[i])) { 27519585STim.Szeto@Sun.COM buf[i] = toupper(buf[i]); 27529585STim.Szeto@Sun.COM continue; 27539585STim.Szeto@Sun.COM } 27549585STim.Szeto@Sun.COM return (-1); 27559585STim.Szeto@Sun.COM } 27569585STim.Szeto@Sun.COM 27579585STim.Szeto@Sun.COM return (0); 27589585STim.Szeto@Sun.COM } 27599585STim.Szeto@Sun.COM 27609585STim.Szeto@Sun.COM /* 27619585STim.Szeto@Sun.COM * Given a numeric suffix, convert the value into a number of bits that the 27629585STim.Szeto@Sun.COM * resulting value must be shifted. 27639585STim.Szeto@Sun.COM * Code lifted from libzfs_util.c 27649585STim.Szeto@Sun.COM */ 27659585STim.Szeto@Sun.COM static int 27669585STim.Szeto@Sun.COM strToShift(const char *buf) 27679585STim.Szeto@Sun.COM { 27689585STim.Szeto@Sun.COM const char *ends = "BKMGTPE"; 27699585STim.Szeto@Sun.COM int i; 27709585STim.Szeto@Sun.COM 27719585STim.Szeto@Sun.COM if (buf[0] == '\0') 27729585STim.Szeto@Sun.COM return (0); 27739585STim.Szeto@Sun.COM 27749585STim.Szeto@Sun.COM for (i = 0; i < strlen(ends); i++) { 27759585STim.Szeto@Sun.COM if (toupper(buf[0]) == ends[i]) 27769585STim.Szeto@Sun.COM return (10*i); 27779585STim.Szeto@Sun.COM } 27789585STim.Szeto@Sun.COM 27799585STim.Szeto@Sun.COM return (-1); 27809585STim.Szeto@Sun.COM } 27819585STim.Szeto@Sun.COM 27829585STim.Szeto@Sun.COM int 27839585STim.Szeto@Sun.COM stmfFreeLuResource(luResource hdl) 27849585STim.Szeto@Sun.COM { 27859585STim.Szeto@Sun.COM int ret = STMF_STATUS_SUCCESS; 27869585STim.Szeto@Sun.COM if (hdl == NULL) { 27879585STim.Szeto@Sun.COM return (STMF_ERROR_INVALID_ARG); 27889585STim.Szeto@Sun.COM } 27899585STim.Szeto@Sun.COM 27909585STim.Szeto@Sun.COM luResourceImpl *hdlImpl = hdl; 27919585STim.Szeto@Sun.COM free(hdlImpl->resource); 27929585STim.Szeto@Sun.COM free(hdlImpl); 27939585STim.Szeto@Sun.COM return (ret); 27949585STim.Szeto@Sun.COM } 27959585STim.Szeto@Sun.COM 27969585STim.Szeto@Sun.COM /* 27979585STim.Szeto@Sun.COM * Convert a string of the form '100G' into a real number. Used when setting 27989585STim.Szeto@Sun.COM * the size of a logical unit. 27999585STim.Szeto@Sun.COM * Code lifted from libzfs_util.c 28009585STim.Szeto@Sun.COM */ 28019585STim.Szeto@Sun.COM static int 28029585STim.Szeto@Sun.COM niceStrToNum(const char *value, uint64_t *num) 28039585STim.Szeto@Sun.COM { 28049585STim.Szeto@Sun.COM char *end; 28059585STim.Szeto@Sun.COM int shift; 28069585STim.Szeto@Sun.COM 28079585STim.Szeto@Sun.COM *num = 0; 28089585STim.Szeto@Sun.COM 28099585STim.Szeto@Sun.COM /* Check to see if this looks like a number. */ 28109585STim.Szeto@Sun.COM if ((value[0] < '0' || value[0] > '9') && value[0] != '.') { 28119585STim.Szeto@Sun.COM return (-1); 28129585STim.Szeto@Sun.COM } 28139585STim.Szeto@Sun.COM 28149585STim.Szeto@Sun.COM /* Rely on stroull() to process the numeric portion. */ 28159585STim.Szeto@Sun.COM errno = 0; 28169585STim.Szeto@Sun.COM *num = strtoull(value, &end, 10); 28179585STim.Szeto@Sun.COM 28189585STim.Szeto@Sun.COM /* 28199585STim.Szeto@Sun.COM * Check for ERANGE, which indicates that the value is too large to fit 28209585STim.Szeto@Sun.COM * in a 64-bit value. 28219585STim.Szeto@Sun.COM */ 28229585STim.Szeto@Sun.COM if (errno == ERANGE) { 28239585STim.Szeto@Sun.COM return (-1); 28249585STim.Szeto@Sun.COM } 28259585STim.Szeto@Sun.COM 28269585STim.Szeto@Sun.COM /* 28279585STim.Szeto@Sun.COM * If we have a decimal value, then do the computation with floating 28289585STim.Szeto@Sun.COM * point arithmetic. Otherwise, use standard arithmetic. 28299585STim.Szeto@Sun.COM */ 28309585STim.Szeto@Sun.COM if (*end == '.') { 28319585STim.Szeto@Sun.COM double fval = strtod(value, &end); 28329585STim.Szeto@Sun.COM 28339585STim.Szeto@Sun.COM if ((shift = strToShift(end)) == -1) { 28349585STim.Szeto@Sun.COM return (-1); 28359585STim.Szeto@Sun.COM } 28369585STim.Szeto@Sun.COM 28379585STim.Szeto@Sun.COM fval *= pow(2, shift); 28389585STim.Szeto@Sun.COM 28399585STim.Szeto@Sun.COM if (fval > UINT64_MAX) { 28409585STim.Szeto@Sun.COM return (-1); 28419585STim.Szeto@Sun.COM } 28429585STim.Szeto@Sun.COM 28439585STim.Szeto@Sun.COM *num = (uint64_t)fval; 28449585STim.Szeto@Sun.COM } else { 28459585STim.Szeto@Sun.COM if ((shift = strToShift(end)) == -1) { 28469585STim.Szeto@Sun.COM return (-1); 28479585STim.Szeto@Sun.COM } 28489585STim.Szeto@Sun.COM 28499585STim.Szeto@Sun.COM /* Check for overflow */ 28509585STim.Szeto@Sun.COM if (shift >= 64 || (*num << shift) >> shift != *num) { 28519585STim.Szeto@Sun.COM return (-1); 28529585STim.Szeto@Sun.COM } 28539585STim.Szeto@Sun.COM 28549585STim.Szeto@Sun.COM *num <<= shift; 28559585STim.Szeto@Sun.COM } 28569585STim.Szeto@Sun.COM 28579585STim.Szeto@Sun.COM return (0); 28589585STim.Szeto@Sun.COM } 28599585STim.Szeto@Sun.COM 28609585STim.Szeto@Sun.COM /* 28617836SJohn.Forte@Sun.COM * stmfCreateTargetGroup 28627836SJohn.Forte@Sun.COM * 28637836SJohn.Forte@Sun.COM * Purpose: Create a local port group 28647836SJohn.Forte@Sun.COM * 28657836SJohn.Forte@Sun.COM * targetGroupName - name of local port group to create 28667836SJohn.Forte@Sun.COM */ 28677836SJohn.Forte@Sun.COM int 28687836SJohn.Forte@Sun.COM stmfCreateTargetGroup(stmfGroupName *targetGroupName) 28697836SJohn.Forte@Sun.COM { 28707836SJohn.Forte@Sun.COM int ret; 28717836SJohn.Forte@Sun.COM int fd; 28727836SJohn.Forte@Sun.COM 28737836SJohn.Forte@Sun.COM if (targetGroupName == NULL || 28747836SJohn.Forte@Sun.COM (strnlen((char *)targetGroupName, sizeof (stmfGroupName)) 28757836SJohn.Forte@Sun.COM == sizeof (stmfGroupName))) { 28767836SJohn.Forte@Sun.COM return (STMF_ERROR_INVALID_ARG); 28777836SJohn.Forte@Sun.COM } 28787836SJohn.Forte@Sun.COM 28797836SJohn.Forte@Sun.COM /* Check to ensure service exists */ 28807836SJohn.Forte@Sun.COM if (psCheckService() != STMF_STATUS_SUCCESS) { 28817836SJohn.Forte@Sun.COM return (STMF_ERROR_SERVICE_NOT_FOUND); 28827836SJohn.Forte@Sun.COM } 28837836SJohn.Forte@Sun.COM 28847836SJohn.Forte@Sun.COM /* call init */ 28857836SJohn.Forte@Sun.COM ret = initializeConfig(); 28867836SJohn.Forte@Sun.COM if (ret != STMF_STATUS_SUCCESS) { 28877836SJohn.Forte@Sun.COM return (ret); 28887836SJohn.Forte@Sun.COM } 28897836SJohn.Forte@Sun.COM 28907836SJohn.Forte@Sun.COM /* 28917836SJohn.Forte@Sun.COM * Open control node for stmf 28927836SJohn.Forte@Sun.COM */ 28937836SJohn.Forte@Sun.COM if ((ret = openStmf(OPEN_STMF, &fd)) != STMF_STATUS_SUCCESS) 28947836SJohn.Forte@Sun.COM return (ret); 28957836SJohn.Forte@Sun.COM 28967836SJohn.Forte@Sun.COM /* 28977836SJohn.Forte@Sun.COM * Add the group to the driver 28987836SJohn.Forte@Sun.COM */ 28997836SJohn.Forte@Sun.COM if ((ret = groupIoctl(fd, STMF_IOCTL_CREATE_TARGET_GROUP, 29007836SJohn.Forte@Sun.COM targetGroupName)) != STMF_STATUS_SUCCESS) { 29017836SJohn.Forte@Sun.COM goto done; 29027836SJohn.Forte@Sun.COM } 29037836SJohn.Forte@Sun.COM 29049585STim.Szeto@Sun.COM if (iGetPersistMethod() == STMF_PERSIST_NONE) { 29059585STim.Szeto@Sun.COM goto done; 29069585STim.Szeto@Sun.COM } 29079585STim.Szeto@Sun.COM 29087836SJohn.Forte@Sun.COM /* 29097836SJohn.Forte@Sun.COM * If the add to the driver was successful, add it to the persistent 29107836SJohn.Forte@Sun.COM * store. 29117836SJohn.Forte@Sun.COM */ 29127836SJohn.Forte@Sun.COM ret = psCreateTargetGroup((char *)targetGroupName); 29137836SJohn.Forte@Sun.COM switch (ret) { 29147836SJohn.Forte@Sun.COM case STMF_PS_SUCCESS: 29157836SJohn.Forte@Sun.COM ret = STMF_STATUS_SUCCESS; 29167836SJohn.Forte@Sun.COM break; 29177836SJohn.Forte@Sun.COM case STMF_PS_ERROR_EXISTS: 29187836SJohn.Forte@Sun.COM ret = STMF_ERROR_EXISTS; 29197836SJohn.Forte@Sun.COM break; 29207836SJohn.Forte@Sun.COM case STMF_PS_ERROR_BUSY: 29217836SJohn.Forte@Sun.COM ret = STMF_ERROR_BUSY; 29227836SJohn.Forte@Sun.COM break; 29237836SJohn.Forte@Sun.COM case STMF_PS_ERROR_SERVICE_NOT_FOUND: 29247836SJohn.Forte@Sun.COM ret = STMF_ERROR_SERVICE_NOT_FOUND; 29257836SJohn.Forte@Sun.COM break; 29267836SJohn.Forte@Sun.COM case STMF_PS_ERROR_VERSION_MISMATCH: 29277836SJohn.Forte@Sun.COM ret = STMF_ERROR_SERVICE_DATA_VERSION; 29287836SJohn.Forte@Sun.COM break; 29297836SJohn.Forte@Sun.COM default: 29307836SJohn.Forte@Sun.COM syslog(LOG_DEBUG, 29317836SJohn.Forte@Sun.COM "stmfCreateTargetGroup:psCreateTargetGroup" 29327836SJohn.Forte@Sun.COM ":error(%d)", ret); 29337836SJohn.Forte@Sun.COM ret = STMF_STATUS_ERROR; 29347836SJohn.Forte@Sun.COM break; 29357836SJohn.Forte@Sun.COM } 29367836SJohn.Forte@Sun.COM 29377836SJohn.Forte@Sun.COM done: 29387836SJohn.Forte@Sun.COM (void) close(fd); 29397836SJohn.Forte@Sun.COM return (ret); 29407836SJohn.Forte@Sun.COM } 29417836SJohn.Forte@Sun.COM 29427836SJohn.Forte@Sun.COM /* 29437836SJohn.Forte@Sun.COM * stmfDeleteHostGroup 29447836SJohn.Forte@Sun.COM * 29457836SJohn.Forte@Sun.COM * Purpose: Delete an initiator or local port group 29467836SJohn.Forte@Sun.COM * 29477836SJohn.Forte@Sun.COM * hostGroupName - group to delete 29487836SJohn.Forte@Sun.COM */ 29497836SJohn.Forte@Sun.COM int 29507836SJohn.Forte@Sun.COM stmfDeleteHostGroup(stmfGroupName *hostGroupName) 29517836SJohn.Forte@Sun.COM { 29527836SJohn.Forte@Sun.COM int ret; 29537836SJohn.Forte@Sun.COM int fd; 29547836SJohn.Forte@Sun.COM 29557836SJohn.Forte@Sun.COM if (hostGroupName == NULL) { 29567836SJohn.Forte@Sun.COM return (STMF_ERROR_INVALID_ARG); 29577836SJohn.Forte@Sun.COM } 29587836SJohn.Forte@Sun.COM 29597836SJohn.Forte@Sun.COM /* Check to ensure service exists */ 29607836SJohn.Forte@Sun.COM if (psCheckService() != STMF_STATUS_SUCCESS) { 29617836SJohn.Forte@Sun.COM return (STMF_ERROR_SERVICE_NOT_FOUND); 29627836SJohn.Forte@Sun.COM } 29637836SJohn.Forte@Sun.COM 29647836SJohn.Forte@Sun.COM /* call init */ 29657836SJohn.Forte@Sun.COM ret = initializeConfig(); 29667836SJohn.Forte@Sun.COM if (ret != STMF_STATUS_SUCCESS) { 29677836SJohn.Forte@Sun.COM return (ret); 29687836SJohn.Forte@Sun.COM } 29697836SJohn.Forte@Sun.COM 29707836SJohn.Forte@Sun.COM /* 29717836SJohn.Forte@Sun.COM * Open control node for stmf 29727836SJohn.Forte@Sun.COM */ 29737836SJohn.Forte@Sun.COM if ((ret = openStmf(OPEN_STMF, &fd)) != STMF_STATUS_SUCCESS) 29747836SJohn.Forte@Sun.COM return (ret); 29757836SJohn.Forte@Sun.COM 29767836SJohn.Forte@Sun.COM /* 29777836SJohn.Forte@Sun.COM * Remove the group from the driver 29787836SJohn.Forte@Sun.COM */ 29797836SJohn.Forte@Sun.COM if ((ret = groupIoctl(fd, STMF_IOCTL_REMOVE_HOST_GROUP, 29807836SJohn.Forte@Sun.COM hostGroupName)) != STMF_STATUS_SUCCESS) { 29817836SJohn.Forte@Sun.COM goto done; 29827836SJohn.Forte@Sun.COM } 29837836SJohn.Forte@Sun.COM 29849585STim.Szeto@Sun.COM if (iGetPersistMethod() == STMF_PERSIST_NONE) { 29859585STim.Szeto@Sun.COM goto done; 29869585STim.Szeto@Sun.COM } 29879585STim.Szeto@Sun.COM 29887836SJohn.Forte@Sun.COM /* 29897836SJohn.Forte@Sun.COM * If the remove from the driver was successful, remove it from the 29907836SJohn.Forte@Sun.COM * persistent store. 29917836SJohn.Forte@Sun.COM */ 29927836SJohn.Forte@Sun.COM ret = psDeleteHostGroup((char *)hostGroupName); 29937836SJohn.Forte@Sun.COM switch (ret) { 29947836SJohn.Forte@Sun.COM case STMF_PS_SUCCESS: 29957836SJohn.Forte@Sun.COM ret = STMF_STATUS_SUCCESS; 29967836SJohn.Forte@Sun.COM break; 29977836SJohn.Forte@Sun.COM case STMF_PS_ERROR_NOT_FOUND: 29987836SJohn.Forte@Sun.COM ret = STMF_ERROR_NOT_FOUND; 29997836SJohn.Forte@Sun.COM break; 30007836SJohn.Forte@Sun.COM case STMF_PS_ERROR_BUSY: 30017836SJohn.Forte@Sun.COM ret = STMF_ERROR_BUSY; 30027836SJohn.Forte@Sun.COM break; 30037836SJohn.Forte@Sun.COM case STMF_PS_ERROR_SERVICE_NOT_FOUND: 30047836SJohn.Forte@Sun.COM ret = STMF_ERROR_SERVICE_NOT_FOUND; 30057836SJohn.Forte@Sun.COM break; 30067836SJohn.Forte@Sun.COM case STMF_PS_ERROR_VERSION_MISMATCH: 30077836SJohn.Forte@Sun.COM ret = STMF_ERROR_SERVICE_DATA_VERSION; 30087836SJohn.Forte@Sun.COM break; 30097836SJohn.Forte@Sun.COM default: 30107836SJohn.Forte@Sun.COM syslog(LOG_DEBUG, 30117836SJohn.Forte@Sun.COM "stmfDeleteHostGroup:psDeleteHostGroup:error(%d)", 30127836SJohn.Forte@Sun.COM ret); 30137836SJohn.Forte@Sun.COM ret = STMF_STATUS_ERROR; 30147836SJohn.Forte@Sun.COM break; 30157836SJohn.Forte@Sun.COM } 30167836SJohn.Forte@Sun.COM 30177836SJohn.Forte@Sun.COM done: 30187836SJohn.Forte@Sun.COM (void) close(fd); 30197836SJohn.Forte@Sun.COM return (ret); 30207836SJohn.Forte@Sun.COM } 30217836SJohn.Forte@Sun.COM 30227836SJohn.Forte@Sun.COM /* 30237836SJohn.Forte@Sun.COM * stmfDeleteTargetGroup 30247836SJohn.Forte@Sun.COM * 30257836SJohn.Forte@Sun.COM * Purpose: Delete an initiator or local port group 30267836SJohn.Forte@Sun.COM * 30277836SJohn.Forte@Sun.COM * targetGroupName - group to delete 30287836SJohn.Forte@Sun.COM */ 30297836SJohn.Forte@Sun.COM int 30307836SJohn.Forte@Sun.COM stmfDeleteTargetGroup(stmfGroupName *targetGroupName) 30317836SJohn.Forte@Sun.COM { 30327836SJohn.Forte@Sun.COM int ret = STMF_STATUS_SUCCESS; 30337836SJohn.Forte@Sun.COM int fd; 30347836SJohn.Forte@Sun.COM 30357836SJohn.Forte@Sun.COM if (targetGroupName == NULL) { 30367836SJohn.Forte@Sun.COM return (STMF_ERROR_INVALID_ARG); 30377836SJohn.Forte@Sun.COM } 30387836SJohn.Forte@Sun.COM 30397836SJohn.Forte@Sun.COM /* Check to ensure service exists */ 30407836SJohn.Forte@Sun.COM if (psCheckService() != STMF_STATUS_SUCCESS) { 30417836SJohn.Forte@Sun.COM return (STMF_ERROR_SERVICE_NOT_FOUND); 30427836SJohn.Forte@Sun.COM } 30437836SJohn.Forte@Sun.COM 30447836SJohn.Forte@Sun.COM /* call init */ 30457836SJohn.Forte@Sun.COM ret = initializeConfig(); 30467836SJohn.Forte@Sun.COM if (ret != STMF_STATUS_SUCCESS) { 30477836SJohn.Forte@Sun.COM return (ret); 30487836SJohn.Forte@Sun.COM } 30497836SJohn.Forte@Sun.COM 30507836SJohn.Forte@Sun.COM /* 30517836SJohn.Forte@Sun.COM * Open control node for stmf 30527836SJohn.Forte@Sun.COM */ 30537836SJohn.Forte@Sun.COM if ((ret = openStmf(OPEN_STMF, &fd)) != STMF_STATUS_SUCCESS) 30547836SJohn.Forte@Sun.COM return (ret); 30557836SJohn.Forte@Sun.COM 30567836SJohn.Forte@Sun.COM /* 30577836SJohn.Forte@Sun.COM * Remove the group from the driver 30587836SJohn.Forte@Sun.COM */ 30597836SJohn.Forte@Sun.COM if ((ret = groupIoctl(fd, STMF_IOCTL_REMOVE_TARGET_GROUP, 30607836SJohn.Forte@Sun.COM targetGroupName)) != STMF_STATUS_SUCCESS) { 30617836SJohn.Forte@Sun.COM goto done; 30627836SJohn.Forte@Sun.COM } 30637836SJohn.Forte@Sun.COM 30649585STim.Szeto@Sun.COM if (iGetPersistMethod() == STMF_PERSIST_NONE) { 30659585STim.Szeto@Sun.COM goto done; 30669585STim.Szeto@Sun.COM } 30679585STim.Szeto@Sun.COM 30687836SJohn.Forte@Sun.COM /* 30697836SJohn.Forte@Sun.COM * If the remove from the driver was successful, remove it from the 30707836SJohn.Forte@Sun.COM * persistent store. 30717836SJohn.Forte@Sun.COM */ 30727836SJohn.Forte@Sun.COM ret = psDeleteTargetGroup((char *)targetGroupName); 30737836SJohn.Forte@Sun.COM switch (ret) { 30747836SJohn.Forte@Sun.COM case STMF_PS_SUCCESS: 30757836SJohn.Forte@Sun.COM ret = STMF_STATUS_SUCCESS; 30767836SJohn.Forte@Sun.COM break; 30777836SJohn.Forte@Sun.COM case STMF_PS_ERROR_NOT_FOUND: 30787836SJohn.Forte@Sun.COM ret = STMF_ERROR_NOT_FOUND; 30797836SJohn.Forte@Sun.COM break; 30807836SJohn.Forte@Sun.COM case STMF_PS_ERROR_BUSY: 30817836SJohn.Forte@Sun.COM ret = STMF_ERROR_BUSY; 30827836SJohn.Forte@Sun.COM break; 30837836SJohn.Forte@Sun.COM case STMF_PS_ERROR_SERVICE_NOT_FOUND: 30847836SJohn.Forte@Sun.COM ret = STMF_ERROR_SERVICE_NOT_FOUND; 30857836SJohn.Forte@Sun.COM break; 30867836SJohn.Forte@Sun.COM case STMF_PS_ERROR_VERSION_MISMATCH: 30877836SJohn.Forte@Sun.COM ret = STMF_ERROR_SERVICE_DATA_VERSION; 30887836SJohn.Forte@Sun.COM break; 30897836SJohn.Forte@Sun.COM default: 30907836SJohn.Forte@Sun.COM syslog(LOG_DEBUG, 30917836SJohn.Forte@Sun.COM "stmfDeleteTargetGroup:psDeleteTargetGroup" 30927836SJohn.Forte@Sun.COM ":error(%d)", ret); 30937836SJohn.Forte@Sun.COM ret = STMF_STATUS_ERROR; 30947836SJohn.Forte@Sun.COM break; 30957836SJohn.Forte@Sun.COM } 30967836SJohn.Forte@Sun.COM 30977836SJohn.Forte@Sun.COM done: 30987836SJohn.Forte@Sun.COM (void) close(fd); 30997836SJohn.Forte@Sun.COM return (ret); 31007836SJohn.Forte@Sun.COM } 31017836SJohn.Forte@Sun.COM 31027836SJohn.Forte@Sun.COM /* 31037836SJohn.Forte@Sun.COM * stmfDevidFromIscsiName 31047836SJohn.Forte@Sun.COM * 31057836SJohn.Forte@Sun.COM * Purpose: convert an iSCSI name to an stmf devid 31067836SJohn.Forte@Sun.COM * 31077836SJohn.Forte@Sun.COM * iscsiName - unicode nul terminated utf-8 encoded iSCSI name 31087836SJohn.Forte@Sun.COM * devid - on success, contains the converted iscsi name 31097836SJohn.Forte@Sun.COM */ 31107836SJohn.Forte@Sun.COM int 31117836SJohn.Forte@Sun.COM stmfDevidFromIscsiName(char *iscsiName, stmfDevid *devid) 31127836SJohn.Forte@Sun.COM { 31137836SJohn.Forte@Sun.COM if (devid == NULL || iscsiName == NULL) 31147836SJohn.Forte@Sun.COM return (STMF_ERROR_INVALID_ARG); 31157836SJohn.Forte@Sun.COM 31167836SJohn.Forte@Sun.COM bzero(devid, sizeof (stmfDevid)); 31177836SJohn.Forte@Sun.COM 31187836SJohn.Forte@Sun.COM /* Validate size of target */ 31197836SJohn.Forte@Sun.COM if ((devid->identLength = strlen(iscsiName)) > MAX_ISCSI_NAME || 31207836SJohn.Forte@Sun.COM devid->identLength < strlen(EUI) || 31217836SJohn.Forte@Sun.COM devid->identLength < strlen(IQN)) { 31227836SJohn.Forte@Sun.COM return (STMF_ERROR_INVALID_ARG); 31237836SJohn.Forte@Sun.COM } 31247836SJohn.Forte@Sun.COM 31257836SJohn.Forte@Sun.COM if ((strncmp(iscsiName, EUI, strlen(EUI)) != 0) && 31267836SJohn.Forte@Sun.COM strncmp(iscsiName, IQN, strlen(IQN)) != 0) { 31277836SJohn.Forte@Sun.COM return (STMF_ERROR_INVALID_ARG); 31287836SJohn.Forte@Sun.COM } 31297836SJohn.Forte@Sun.COM 31307836SJohn.Forte@Sun.COM /* copy UTF-8 bytes to ident */ 31317836SJohn.Forte@Sun.COM bcopy(iscsiName, devid->ident, devid->identLength); 31327836SJohn.Forte@Sun.COM 31337836SJohn.Forte@Sun.COM return (STMF_STATUS_SUCCESS); 31347836SJohn.Forte@Sun.COM } 31357836SJohn.Forte@Sun.COM 31367836SJohn.Forte@Sun.COM /* 31377836SJohn.Forte@Sun.COM * stmfDevidFromWwn 31387836SJohn.Forte@Sun.COM * 31397836SJohn.Forte@Sun.COM * Purpose: convert a WWN to an stmf devid 31407836SJohn.Forte@Sun.COM * 31417836SJohn.Forte@Sun.COM * wwn - 8-byte wwn identifier 31427836SJohn.Forte@Sun.COM * devid - on success, contains the converted wwn 31437836SJohn.Forte@Sun.COM */ 31447836SJohn.Forte@Sun.COM int 31457836SJohn.Forte@Sun.COM stmfDevidFromWwn(uchar_t *wwn, stmfDevid *devid) 31467836SJohn.Forte@Sun.COM { 31477836SJohn.Forte@Sun.COM if (wwn == NULL || devid == NULL) 31487836SJohn.Forte@Sun.COM return (STMF_ERROR_INVALID_ARG); 31497836SJohn.Forte@Sun.COM 31507836SJohn.Forte@Sun.COM bzero(devid, sizeof (stmfDevid)); 31517836SJohn.Forte@Sun.COM 31527836SJohn.Forte@Sun.COM /* Copy eui prefix */ 31537836SJohn.Forte@Sun.COM (void) bcopy(WWN, devid->ident, strlen(WWN)); 31547836SJohn.Forte@Sun.COM 31557836SJohn.Forte@Sun.COM /* Convert to ASCII uppercase hexadecimal string */ 31567836SJohn.Forte@Sun.COM (void) snprintf((char *)&devid->ident[strlen(WWN)], 31577836SJohn.Forte@Sun.COM sizeof (devid->ident), "%02X%02X%02X%02X%02X%02X%02X%02X", 31587836SJohn.Forte@Sun.COM wwn[0], wwn[1], wwn[2], wwn[3], wwn[4], wwn[5], wwn[6], wwn[7]); 31597836SJohn.Forte@Sun.COM 31607836SJohn.Forte@Sun.COM devid->identLength = strlen((char *)devid->ident); 31617836SJohn.Forte@Sun.COM 31627836SJohn.Forte@Sun.COM return (STMF_STATUS_SUCCESS); 31637836SJohn.Forte@Sun.COM } 31647836SJohn.Forte@Sun.COM 31657836SJohn.Forte@Sun.COM /* 31667836SJohn.Forte@Sun.COM * stmfFreeMemory 31677836SJohn.Forte@Sun.COM * 31687836SJohn.Forte@Sun.COM * Purpose: Free memory allocated by this library 31697836SJohn.Forte@Sun.COM * 31707836SJohn.Forte@Sun.COM * memory - previously allocated pointer of memory managed by library 31717836SJohn.Forte@Sun.COM */ 31727836SJohn.Forte@Sun.COM void 31737836SJohn.Forte@Sun.COM stmfFreeMemory(void *memory) 31747836SJohn.Forte@Sun.COM { 31757836SJohn.Forte@Sun.COM free(memory); 31767836SJohn.Forte@Sun.COM } 31777836SJohn.Forte@Sun.COM 31787836SJohn.Forte@Sun.COM /* 31799585STim.Szeto@Sun.COM * get host group, target group list from stmf 31807836SJohn.Forte@Sun.COM * 31819585STim.Szeto@Sun.COM * groupType - HOST_GROUP, TARGET_GROUP 31827836SJohn.Forte@Sun.COM */ 31839585STim.Szeto@Sun.COM static int 31849585STim.Szeto@Sun.COM groupListIoctl(stmfGroupList **groupList, int groupType) 31859585STim.Szeto@Sun.COM { 31869585STim.Szeto@Sun.COM int ret; 31879585STim.Szeto@Sun.COM int fd; 31889585STim.Szeto@Sun.COM int ioctlRet; 31899585STim.Szeto@Sun.COM int i; 31909585STim.Szeto@Sun.COM int cmd; 31919585STim.Szeto@Sun.COM stmf_iocdata_t stmfIoctl; 31929585STim.Szeto@Sun.COM /* framework group list */ 31939585STim.Szeto@Sun.COM stmf_group_name_t *iGroupList = NULL; 31949585STim.Szeto@Sun.COM uint32_t groupListSize; 31959585STim.Szeto@Sun.COM 31969585STim.Szeto@Sun.COM if (groupList == NULL) { 31979585STim.Szeto@Sun.COM return (STMF_ERROR_INVALID_ARG); 31989585STim.Szeto@Sun.COM } 31999585STim.Szeto@Sun.COM 32009585STim.Szeto@Sun.COM if (groupType == HOST_GROUP) { 32019585STim.Szeto@Sun.COM cmd = STMF_IOCTL_GET_HG_LIST; 32029585STim.Szeto@Sun.COM } else if (groupType == TARGET_GROUP) { 32039585STim.Szeto@Sun.COM cmd = STMF_IOCTL_GET_TG_LIST; 32049585STim.Szeto@Sun.COM } else { 32059585STim.Szeto@Sun.COM return (STMF_ERROR_INVALID_ARG); 32069585STim.Szeto@Sun.COM } 32079585STim.Szeto@Sun.COM 32089585STim.Szeto@Sun.COM /* call init */ 32099585STim.Szeto@Sun.COM ret = initializeConfig(); 32109585STim.Szeto@Sun.COM if (ret != STMF_STATUS_SUCCESS) { 32119585STim.Szeto@Sun.COM return (ret); 32129585STim.Szeto@Sun.COM } 32139585STim.Szeto@Sun.COM 32149585STim.Szeto@Sun.COM /* 32159585STim.Szeto@Sun.COM * Open control node for stmf 32169585STim.Szeto@Sun.COM */ 32179585STim.Szeto@Sun.COM if ((ret = openStmf(OPEN_STMF, &fd)) != STMF_STATUS_SUCCESS) 32189585STim.Szeto@Sun.COM return (ret); 32199585STim.Szeto@Sun.COM 32209585STim.Szeto@Sun.COM /* 32219585STim.Szeto@Sun.COM * Allocate ioctl input buffer 32229585STim.Szeto@Sun.COM */ 32239585STim.Szeto@Sun.COM groupListSize = ALLOC_GROUP; 32249585STim.Szeto@Sun.COM groupListSize = groupListSize * (sizeof (stmf_group_name_t)); 32259585STim.Szeto@Sun.COM iGroupList = (stmf_group_name_t *)calloc(1, groupListSize); 32269585STim.Szeto@Sun.COM if (iGroupList == NULL) { 32279585STim.Szeto@Sun.COM ret = STMF_ERROR_NOMEM; 32289585STim.Szeto@Sun.COM goto done; 32299585STim.Szeto@Sun.COM } 32309585STim.Szeto@Sun.COM 32319585STim.Szeto@Sun.COM bzero(&stmfIoctl, sizeof (stmfIoctl)); 32329585STim.Szeto@Sun.COM /* 32339585STim.Szeto@Sun.COM * Issue ioctl to get the group list 32349585STim.Szeto@Sun.COM */ 32359585STim.Szeto@Sun.COM stmfIoctl.stmf_version = STMF_VERSION_1; 32369585STim.Szeto@Sun.COM stmfIoctl.stmf_obuf_size = groupListSize; 32379585STim.Szeto@Sun.COM stmfIoctl.stmf_obuf = (uint64_t)(unsigned long)iGroupList; 32389585STim.Szeto@Sun.COM ioctlRet = ioctl(fd, cmd, &stmfIoctl); 32399585STim.Szeto@Sun.COM if (ioctlRet != 0) { 32409585STim.Szeto@Sun.COM switch (errno) { 32419585STim.Szeto@Sun.COM case EBUSY: 32429585STim.Szeto@Sun.COM ret = STMF_ERROR_BUSY; 32439585STim.Szeto@Sun.COM break; 32449585STim.Szeto@Sun.COM case EPERM: 32459585STim.Szeto@Sun.COM case EACCES: 32469585STim.Szeto@Sun.COM ret = STMF_ERROR_PERM; 32479585STim.Szeto@Sun.COM break; 32489585STim.Szeto@Sun.COM default: 32499585STim.Szeto@Sun.COM syslog(LOG_DEBUG, 32509585STim.Szeto@Sun.COM "groupListIoctl:ioctl errno(%d)", 32519585STim.Szeto@Sun.COM errno); 32529585STim.Szeto@Sun.COM ret = STMF_STATUS_ERROR; 32539585STim.Szeto@Sun.COM break; 32549585STim.Szeto@Sun.COM } 32559585STim.Szeto@Sun.COM goto done; 32569585STim.Szeto@Sun.COM } 32579585STim.Szeto@Sun.COM /* 32589585STim.Szeto@Sun.COM * Check whether input buffer was large enough 32599585STim.Szeto@Sun.COM */ 32609585STim.Szeto@Sun.COM if (stmfIoctl.stmf_obuf_max_nentries > ALLOC_GROUP) { 32619585STim.Szeto@Sun.COM groupListSize = stmfIoctl.stmf_obuf_max_nentries * 32629585STim.Szeto@Sun.COM sizeof (stmf_group_name_t); 32639585STim.Szeto@Sun.COM iGroupList = realloc(iGroupList, groupListSize); 32649585STim.Szeto@Sun.COM if (iGroupList == NULL) { 32659585STim.Szeto@Sun.COM ret = STMF_ERROR_NOMEM; 32669585STim.Szeto@Sun.COM goto done; 32679585STim.Szeto@Sun.COM } 32689585STim.Szeto@Sun.COM stmfIoctl.stmf_obuf_size = groupListSize; 32699585STim.Szeto@Sun.COM stmfIoctl.stmf_obuf = (uint64_t)(unsigned long)iGroupList; 32709585STim.Szeto@Sun.COM ioctlRet = ioctl(fd, cmd, &stmfIoctl); 32719585STim.Szeto@Sun.COM if (ioctlRet != 0) { 32729585STim.Szeto@Sun.COM switch (errno) { 32739585STim.Szeto@Sun.COM case EBUSY: 32749585STim.Szeto@Sun.COM ret = STMF_ERROR_BUSY; 32759585STim.Szeto@Sun.COM break; 32769585STim.Szeto@Sun.COM case EPERM: 32779585STim.Szeto@Sun.COM case EACCES: 32789585STim.Szeto@Sun.COM ret = STMF_ERROR_PERM; 32799585STim.Szeto@Sun.COM break; 32809585STim.Szeto@Sun.COM default: 32819585STim.Szeto@Sun.COM syslog(LOG_DEBUG, 32829585STim.Szeto@Sun.COM "groupListIoctl:ioctl errno(%d)", 32839585STim.Szeto@Sun.COM errno); 32849585STim.Szeto@Sun.COM ret = STMF_STATUS_ERROR; 32859585STim.Szeto@Sun.COM break; 32869585STim.Szeto@Sun.COM } 32879585STim.Szeto@Sun.COM goto done; 32889585STim.Szeto@Sun.COM } 32899585STim.Szeto@Sun.COM } 32909585STim.Szeto@Sun.COM 32919585STim.Szeto@Sun.COM /* allocate and copy to caller's buffer */ 329210236SSrivijitha.Dugganapalli@Sun.COM *groupList = (stmfGroupList *)calloc(1, sizeof (stmfGroupList) + 329310236SSrivijitha.Dugganapalli@Sun.COM sizeof (stmfGroupName) * stmfIoctl.stmf_obuf_nentries); 32949585STim.Szeto@Sun.COM if (*groupList == NULL) { 32959585STim.Szeto@Sun.COM ret = STMF_ERROR_NOMEM; 32969585STim.Szeto@Sun.COM goto done; 32979585STim.Szeto@Sun.COM } 32989585STim.Szeto@Sun.COM (*groupList)->cnt = stmfIoctl.stmf_obuf_nentries; 32999585STim.Szeto@Sun.COM for (i = 0; i < stmfIoctl.stmf_obuf_nentries; i++) { 330010113SNattuvetty.Bhavyan@Sun.COM bcopy(iGroupList[i].name, (*groupList)->name[i], 33019585STim.Szeto@Sun.COM sizeof (stmfGroupName)); 33029585STim.Szeto@Sun.COM } 33039585STim.Szeto@Sun.COM 33049585STim.Szeto@Sun.COM done: 33059585STim.Szeto@Sun.COM free(iGroupList); 33069585STim.Szeto@Sun.COM (void) close(fd); 33079585STim.Szeto@Sun.COM return (ret); 33089585STim.Szeto@Sun.COM } 33099585STim.Szeto@Sun.COM 33109585STim.Szeto@Sun.COM /* 33119585STim.Szeto@Sun.COM * get host group members, target group members from stmf 33129585STim.Szeto@Sun.COM * 33139585STim.Szeto@Sun.COM * groupProps - allocated on success 33149585STim.Szeto@Sun.COM * 33159585STim.Szeto@Sun.COM * groupType - HOST_GROUP, TARGET_GROUP 33169585STim.Szeto@Sun.COM */ 33179585STim.Szeto@Sun.COM static int 33189585STim.Szeto@Sun.COM groupMemberListIoctl(stmfGroupName *groupName, stmfGroupProperties **groupProps, 33199585STim.Szeto@Sun.COM int groupType) 33207836SJohn.Forte@Sun.COM { 33217836SJohn.Forte@Sun.COM int ret; 33229585STim.Szeto@Sun.COM int fd; 33239585STim.Szeto@Sun.COM int ioctlRet; 33249585STim.Szeto@Sun.COM int i; 33259585STim.Szeto@Sun.COM int cmd; 33269585STim.Szeto@Sun.COM stmf_iocdata_t stmfIoctl; 33279585STim.Szeto@Sun.COM /* framework group list */ 33289585STim.Szeto@Sun.COM stmf_group_name_t iGroupName; 33299585STim.Szeto@Sun.COM stmf_ge_ident_t *iGroupMembers; 33309585STim.Szeto@Sun.COM uint32_t groupListSize; 33319585STim.Szeto@Sun.COM 33329585STim.Szeto@Sun.COM if (groupName == NULL) { 33339585STim.Szeto@Sun.COM return (STMF_ERROR_INVALID_ARG); 33349585STim.Szeto@Sun.COM } 33359585STim.Szeto@Sun.COM 33369585STim.Szeto@Sun.COM if (groupType == HOST_GROUP) { 33379585STim.Szeto@Sun.COM cmd = STMF_IOCTL_GET_HG_ENTRIES; 33389585STim.Szeto@Sun.COM } else if (groupType == TARGET_GROUP) { 33399585STim.Szeto@Sun.COM cmd = STMF_IOCTL_GET_TG_ENTRIES; 33409585STim.Szeto@Sun.COM } else { 33417836SJohn.Forte@Sun.COM return (STMF_ERROR_INVALID_ARG); 33427836SJohn.Forte@Sun.COM } 33437836SJohn.Forte@Sun.COM 33449585STim.Szeto@Sun.COM /* call init */ 33459585STim.Szeto@Sun.COM ret = initializeConfig(); 33469585STim.Szeto@Sun.COM if (ret != STMF_STATUS_SUCCESS) { 33479585STim.Szeto@Sun.COM return (ret); 33489585STim.Szeto@Sun.COM } 33499585STim.Szeto@Sun.COM 33509585STim.Szeto@Sun.COM /* 33519585STim.Szeto@Sun.COM * Open control node for stmf 33529585STim.Szeto@Sun.COM */ 33539585STim.Szeto@Sun.COM if ((ret = openStmf(OPEN_STMF, &fd)) != STMF_STATUS_SUCCESS) 33549585STim.Szeto@Sun.COM return (ret); 33559585STim.Szeto@Sun.COM 33569585STim.Szeto@Sun.COM bzero(&iGroupName, sizeof (iGroupName)); 33579585STim.Szeto@Sun.COM 33589585STim.Szeto@Sun.COM bcopy(groupName, &iGroupName.name, strlen((char *)groupName)); 33599585STim.Szeto@Sun.COM 33609585STim.Szeto@Sun.COM iGroupName.name_size = strlen((char *)groupName); 33619585STim.Szeto@Sun.COM 33629585STim.Szeto@Sun.COM /* 33639585STim.Szeto@Sun.COM * Allocate ioctl input buffer 33649585STim.Szeto@Sun.COM */ 33659585STim.Szeto@Sun.COM groupListSize = ALLOC_GRP_MEMBER; 33669585STim.Szeto@Sun.COM groupListSize = groupListSize * (sizeof (stmf_ge_ident_t)); 33679585STim.Szeto@Sun.COM iGroupMembers = (stmf_ge_ident_t *)calloc(1, groupListSize); 33689585STim.Szeto@Sun.COM if (iGroupMembers == NULL) { 33699585STim.Szeto@Sun.COM ret = STMF_ERROR_NOMEM; 33709585STim.Szeto@Sun.COM goto done; 33719585STim.Szeto@Sun.COM } 33729585STim.Szeto@Sun.COM 33739585STim.Szeto@Sun.COM bzero(&stmfIoctl, sizeof (stmfIoctl)); 33749585STim.Szeto@Sun.COM /* 33759585STim.Szeto@Sun.COM * Issue ioctl to get the group list 33769585STim.Szeto@Sun.COM */ 33779585STim.Szeto@Sun.COM stmfIoctl.stmf_version = STMF_VERSION_1; 33789585STim.Szeto@Sun.COM stmfIoctl.stmf_ibuf = (uint64_t)(unsigned long)&iGroupName; 33799585STim.Szeto@Sun.COM stmfIoctl.stmf_ibuf_size = sizeof (stmf_group_name_t); 33809585STim.Szeto@Sun.COM stmfIoctl.stmf_obuf_size = groupListSize; 33819585STim.Szeto@Sun.COM stmfIoctl.stmf_obuf = (uint64_t)(unsigned long)iGroupMembers; 33829585STim.Szeto@Sun.COM ioctlRet = ioctl(fd, cmd, &stmfIoctl); 33839585STim.Szeto@Sun.COM if (ioctlRet != 0) { 33849585STim.Szeto@Sun.COM switch (errno) { 33859585STim.Szeto@Sun.COM case EBUSY: 33869585STim.Szeto@Sun.COM ret = STMF_ERROR_BUSY; 33879585STim.Szeto@Sun.COM break; 33889585STim.Szeto@Sun.COM case EPERM: 33899585STim.Szeto@Sun.COM case EACCES: 33909585STim.Szeto@Sun.COM ret = STMF_ERROR_PERM; 33919585STim.Szeto@Sun.COM break; 33929585STim.Szeto@Sun.COM default: 33939585STim.Szeto@Sun.COM syslog(LOG_DEBUG, 33949585STim.Szeto@Sun.COM "groupListIoctl:ioctl errno(%d)", 33959585STim.Szeto@Sun.COM errno); 33969585STim.Szeto@Sun.COM ret = STMF_STATUS_ERROR; 33979585STim.Szeto@Sun.COM break; 33989585STim.Szeto@Sun.COM } 33999585STim.Szeto@Sun.COM goto done; 34009585STim.Szeto@Sun.COM } 34019585STim.Szeto@Sun.COM /* 34029585STim.Szeto@Sun.COM * Check whether input buffer was large enough 34039585STim.Szeto@Sun.COM */ 34049585STim.Szeto@Sun.COM if (stmfIoctl.stmf_obuf_max_nentries > ALLOC_GRP_MEMBER) { 34059585STim.Szeto@Sun.COM groupListSize = stmfIoctl.stmf_obuf_max_nentries * 34069585STim.Szeto@Sun.COM sizeof (stmf_ge_ident_t); 34079585STim.Szeto@Sun.COM iGroupMembers = realloc(iGroupMembers, groupListSize); 34089585STim.Szeto@Sun.COM if (iGroupMembers == NULL) { 34099585STim.Szeto@Sun.COM ret = STMF_ERROR_NOMEM; 34109585STim.Szeto@Sun.COM goto done; 34119585STim.Szeto@Sun.COM } 34129585STim.Szeto@Sun.COM stmfIoctl.stmf_ibuf = (uint64_t)(unsigned long)&iGroupName; 34139585STim.Szeto@Sun.COM stmfIoctl.stmf_ibuf_size = sizeof (stmf_group_name_t); 34149585STim.Szeto@Sun.COM stmfIoctl.stmf_obuf_size = groupListSize; 34159585STim.Szeto@Sun.COM stmfIoctl.stmf_obuf = (uint64_t)(unsigned long)iGroupMembers; 34169585STim.Szeto@Sun.COM ioctlRet = ioctl(fd, cmd, &stmfIoctl); 34179585STim.Szeto@Sun.COM if (ioctlRet != 0) { 34189585STim.Szeto@Sun.COM switch (errno) { 34199585STim.Szeto@Sun.COM case EBUSY: 34209585STim.Szeto@Sun.COM ret = STMF_ERROR_BUSY; 34219585STim.Szeto@Sun.COM break; 34229585STim.Szeto@Sun.COM case EPERM: 34239585STim.Szeto@Sun.COM case EACCES: 34249585STim.Szeto@Sun.COM ret = STMF_ERROR_PERM; 34259585STim.Szeto@Sun.COM break; 34269585STim.Szeto@Sun.COM default: 34279585STim.Szeto@Sun.COM syslog(LOG_DEBUG, 34289585STim.Szeto@Sun.COM "groupListIoctl:ioctl errno(%d)", 34299585STim.Szeto@Sun.COM errno); 34309585STim.Szeto@Sun.COM ret = STMF_STATUS_ERROR; 34319585STim.Szeto@Sun.COM break; 34329585STim.Szeto@Sun.COM } 34339585STim.Szeto@Sun.COM goto done; 34349585STim.Szeto@Sun.COM } 34359585STim.Szeto@Sun.COM } 34369585STim.Szeto@Sun.COM 34379585STim.Szeto@Sun.COM /* allocate and copy to caller's buffer */ 34389585STim.Szeto@Sun.COM *groupProps = (stmfGroupProperties *)calloc(1, 343910236SSrivijitha.Dugganapalli@Sun.COM sizeof (stmfGroupProperties) + 344010236SSrivijitha.Dugganapalli@Sun.COM sizeof (stmfDevid) * stmfIoctl.stmf_obuf_nentries); 34419585STim.Szeto@Sun.COM if (*groupProps == NULL) { 34429585STim.Szeto@Sun.COM ret = STMF_ERROR_NOMEM; 34439585STim.Szeto@Sun.COM goto done; 34449585STim.Szeto@Sun.COM } 34459585STim.Szeto@Sun.COM (*groupProps)->cnt = stmfIoctl.stmf_obuf_nentries; 34469585STim.Szeto@Sun.COM for (i = 0; i < stmfIoctl.stmf_obuf_nentries; i++) { 34479585STim.Szeto@Sun.COM (*groupProps)->name[i].identLength = 344810113SNattuvetty.Bhavyan@Sun.COM iGroupMembers[i].ident_size; 344910113SNattuvetty.Bhavyan@Sun.COM bcopy(iGroupMembers[i].ident, (*groupProps)->name[i].ident, 345010113SNattuvetty.Bhavyan@Sun.COM iGroupMembers[i].ident_size); 34519585STim.Szeto@Sun.COM } 34529585STim.Szeto@Sun.COM 34539585STim.Szeto@Sun.COM done: 34549585STim.Szeto@Sun.COM free(iGroupMembers); 34559585STim.Szeto@Sun.COM (void) close(fd); 34569585STim.Szeto@Sun.COM return (ret); 34579585STim.Szeto@Sun.COM } 34589585STim.Szeto@Sun.COM 34599585STim.Szeto@Sun.COM /* 34609585STim.Szeto@Sun.COM * Purpose: access persistent config data for host groups and target groups 34619585STim.Szeto@Sun.COM */ 34629585STim.Szeto@Sun.COM static int 34639585STim.Szeto@Sun.COM iLoadGroupFromPs(stmfGroupList **groupList, int type) 34649585STim.Szeto@Sun.COM { 34659585STim.Szeto@Sun.COM int ret; 34669585STim.Szeto@Sun.COM 34679585STim.Szeto@Sun.COM if (groupList == NULL) { 34689585STim.Szeto@Sun.COM return (STMF_ERROR_INVALID_ARG); 34699585STim.Szeto@Sun.COM } 34709585STim.Szeto@Sun.COM 34719585STim.Szeto@Sun.COM if (type == HOST_GROUP) { 34729585STim.Szeto@Sun.COM ret = psGetHostGroupList(groupList); 34739585STim.Szeto@Sun.COM } else if (type == TARGET_GROUP) { 34749585STim.Szeto@Sun.COM ret = psGetTargetGroupList(groupList); 34759585STim.Szeto@Sun.COM } else { 34769585STim.Szeto@Sun.COM return (STMF_ERROR_INVALID_ARG); 34779585STim.Szeto@Sun.COM } 34787836SJohn.Forte@Sun.COM switch (ret) { 34797836SJohn.Forte@Sun.COM case STMF_PS_SUCCESS: 34807836SJohn.Forte@Sun.COM ret = STMF_STATUS_SUCCESS; 34817836SJohn.Forte@Sun.COM break; 34827836SJohn.Forte@Sun.COM case STMF_PS_ERROR_NOT_FOUND: 34837836SJohn.Forte@Sun.COM ret = STMF_ERROR_NOT_FOUND; 34847836SJohn.Forte@Sun.COM break; 34857836SJohn.Forte@Sun.COM case STMF_PS_ERROR_BUSY: 34867836SJohn.Forte@Sun.COM ret = STMF_ERROR_BUSY; 34877836SJohn.Forte@Sun.COM break; 34887836SJohn.Forte@Sun.COM case STMF_PS_ERROR_SERVICE_NOT_FOUND: 34897836SJohn.Forte@Sun.COM ret = STMF_ERROR_SERVICE_NOT_FOUND; 34907836SJohn.Forte@Sun.COM break; 34917836SJohn.Forte@Sun.COM case STMF_PS_ERROR_VERSION_MISMATCH: 34927836SJohn.Forte@Sun.COM ret = STMF_ERROR_SERVICE_DATA_VERSION; 34937836SJohn.Forte@Sun.COM break; 34947836SJohn.Forte@Sun.COM default: 34957836SJohn.Forte@Sun.COM syslog(LOG_DEBUG, 34967836SJohn.Forte@Sun.COM "stmfGetHostGroupList:psGetHostGroupList:error(%d)", 34977836SJohn.Forte@Sun.COM ret); 34987836SJohn.Forte@Sun.COM ret = STMF_STATUS_ERROR; 34997836SJohn.Forte@Sun.COM break; 35007836SJohn.Forte@Sun.COM } 35017836SJohn.Forte@Sun.COM 35027836SJohn.Forte@Sun.COM return (ret); 35037836SJohn.Forte@Sun.COM } 35047836SJohn.Forte@Sun.COM 35057836SJohn.Forte@Sun.COM /* 35069585STim.Szeto@Sun.COM * stmfGetHostGroupList 35077836SJohn.Forte@Sun.COM * 35089585STim.Szeto@Sun.COM * Purpose: Retrieves the list of initiator group oids 35099585STim.Szeto@Sun.COM * 35109585STim.Szeto@Sun.COM * hostGroupList - pointer to pointer to hostGroupList structure 35119585STim.Szeto@Sun.COM * on success, this contains the host group list. 35127836SJohn.Forte@Sun.COM */ 35137836SJohn.Forte@Sun.COM int 35149585STim.Szeto@Sun.COM stmfGetHostGroupList(stmfGroupList **hostGroupList) 35159585STim.Szeto@Sun.COM { 35169585STim.Szeto@Sun.COM int ret = STMF_STATUS_ERROR; 35179585STim.Szeto@Sun.COM 35189585STim.Szeto@Sun.COM if (hostGroupList == NULL) { 35199585STim.Szeto@Sun.COM return (STMF_ERROR_INVALID_ARG); 35209585STim.Szeto@Sun.COM } 35219585STim.Szeto@Sun.COM 35229585STim.Szeto@Sun.COM ret = groupListIoctl(hostGroupList, HOST_GROUP); 35239585STim.Szeto@Sun.COM return (ret); 35249585STim.Szeto@Sun.COM } 35259585STim.Szeto@Sun.COM 35269585STim.Szeto@Sun.COM 35279585STim.Szeto@Sun.COM /* 35289585STim.Szeto@Sun.COM * Purpose: access persistent config data for host groups and target groups 35299585STim.Szeto@Sun.COM */ 35309585STim.Szeto@Sun.COM static int 35319585STim.Szeto@Sun.COM iLoadGroupMembersFromPs(stmfGroupName *groupName, 35329585STim.Szeto@Sun.COM stmfGroupProperties **groupProp, int type) 35337836SJohn.Forte@Sun.COM { 35347836SJohn.Forte@Sun.COM int ret; 35357836SJohn.Forte@Sun.COM 35369585STim.Szeto@Sun.COM if (groupName == NULL) { 35377836SJohn.Forte@Sun.COM return (STMF_ERROR_INVALID_ARG); 35387836SJohn.Forte@Sun.COM } 35397836SJohn.Forte@Sun.COM 35409585STim.Szeto@Sun.COM if (type == HOST_GROUP) { 35419585STim.Szeto@Sun.COM ret = psGetHostGroupMemberList((char *)groupName, groupProp); 35429585STim.Szeto@Sun.COM } else if (type == TARGET_GROUP) { 35439585STim.Szeto@Sun.COM ret = psGetTargetGroupMemberList((char *)groupName, groupProp); 35449585STim.Szeto@Sun.COM } else { 35459585STim.Szeto@Sun.COM return (STMF_ERROR_INVALID_ARG); 35469585STim.Szeto@Sun.COM } 35477836SJohn.Forte@Sun.COM switch (ret) { 35487836SJohn.Forte@Sun.COM case STMF_PS_SUCCESS: 35497836SJohn.Forte@Sun.COM ret = STMF_STATUS_SUCCESS; 35507836SJohn.Forte@Sun.COM break; 35517836SJohn.Forte@Sun.COM case STMF_PS_ERROR_NOT_FOUND: 35527836SJohn.Forte@Sun.COM ret = STMF_ERROR_NOT_FOUND; 35537836SJohn.Forte@Sun.COM break; 35547836SJohn.Forte@Sun.COM case STMF_PS_ERROR_BUSY: 35557836SJohn.Forte@Sun.COM ret = STMF_ERROR_BUSY; 35567836SJohn.Forte@Sun.COM break; 35577836SJohn.Forte@Sun.COM case STMF_PS_ERROR_SERVICE_NOT_FOUND: 35587836SJohn.Forte@Sun.COM ret = STMF_ERROR_SERVICE_NOT_FOUND; 35597836SJohn.Forte@Sun.COM break; 35607836SJohn.Forte@Sun.COM case STMF_PS_ERROR_VERSION_MISMATCH: 35617836SJohn.Forte@Sun.COM ret = STMF_ERROR_SERVICE_DATA_VERSION; 35627836SJohn.Forte@Sun.COM break; 35637836SJohn.Forte@Sun.COM default: 35647836SJohn.Forte@Sun.COM syslog(LOG_DEBUG, 35659585STim.Szeto@Sun.COM "iLoadGroupMembersFromPs:psGetHostGroupList:" 35669585STim.Szeto@Sun.COM "error(%d)", ret); 35677836SJohn.Forte@Sun.COM ret = STMF_STATUS_ERROR; 35687836SJohn.Forte@Sun.COM break; 35697836SJohn.Forte@Sun.COM } 35707836SJohn.Forte@Sun.COM 35717836SJohn.Forte@Sun.COM return (ret); 35727836SJohn.Forte@Sun.COM } 35737836SJohn.Forte@Sun.COM 35747836SJohn.Forte@Sun.COM /* 35759585STim.Szeto@Sun.COM * stmfGetHostGroupMembers 35769585STim.Szeto@Sun.COM * 35779585STim.Szeto@Sun.COM * Purpose: Retrieves the group properties for a host group 35789585STim.Szeto@Sun.COM * 35799585STim.Szeto@Sun.COM * groupName - name of group for which to retrieve host group members. 35809585STim.Szeto@Sun.COM * groupProp - pointer to pointer to stmfGroupProperties structure 35819585STim.Szeto@Sun.COM * on success, this contains the list of group members. 35829585STim.Szeto@Sun.COM */ 35839585STim.Szeto@Sun.COM int 35849585STim.Szeto@Sun.COM stmfGetHostGroupMembers(stmfGroupName *groupName, 35859585STim.Szeto@Sun.COM stmfGroupProperties **groupProp) 35869585STim.Szeto@Sun.COM { 35879585STim.Szeto@Sun.COM int ret; 35889585STim.Szeto@Sun.COM 35899585STim.Szeto@Sun.COM if (groupName == NULL || groupProp == NULL) { 35909585STim.Szeto@Sun.COM return (STMF_ERROR_INVALID_ARG); 35919585STim.Szeto@Sun.COM } 35929585STim.Szeto@Sun.COM 35939585STim.Szeto@Sun.COM ret = groupMemberListIoctl(groupName, groupProp, HOST_GROUP); 35949585STim.Szeto@Sun.COM 35959585STim.Szeto@Sun.COM return (ret); 35969585STim.Szeto@Sun.COM } 35979585STim.Szeto@Sun.COM 35989585STim.Szeto@Sun.COM /* 35997836SJohn.Forte@Sun.COM * stmfGetProviderData 36007836SJohn.Forte@Sun.COM * 36017836SJohn.Forte@Sun.COM * Purpose: Get provider data list 36027836SJohn.Forte@Sun.COM * 36037836SJohn.Forte@Sun.COM * providerName - name of provider for which to retrieve the data 36047836SJohn.Forte@Sun.COM * nvl - pointer to nvlist_t pointer which will contain the nvlist data 36057836SJohn.Forte@Sun.COM * retrieved. 36067836SJohn.Forte@Sun.COM * providerType - type of provider for which to retrieve data. 36077836SJohn.Forte@Sun.COM * STMF_LU_PROVIDER_TYPE 36087836SJohn.Forte@Sun.COM * STMF_PORT_PROVIDER_TYPE 36097836SJohn.Forte@Sun.COM */ 36107836SJohn.Forte@Sun.COM int 36117836SJohn.Forte@Sun.COM stmfGetProviderData(char *providerName, nvlist_t **nvl, int providerType) 36127836SJohn.Forte@Sun.COM { 36137836SJohn.Forte@Sun.COM return (stmfGetProviderDataProt(providerName, nvl, providerType, 36147836SJohn.Forte@Sun.COM NULL)); 36157836SJohn.Forte@Sun.COM } 36167836SJohn.Forte@Sun.COM 36177836SJohn.Forte@Sun.COM /* 36187836SJohn.Forte@Sun.COM * stmfGetProviderDataProt 36197836SJohn.Forte@Sun.COM * 36207836SJohn.Forte@Sun.COM * Purpose: Get provider data list with token 36217836SJohn.Forte@Sun.COM * 36227836SJohn.Forte@Sun.COM * providerName - name of provider for which to retrieve the data 36237836SJohn.Forte@Sun.COM * nvl - pointer to nvlist_t pointer which will contain the nvlist data 36247836SJohn.Forte@Sun.COM * retrieved. 36257836SJohn.Forte@Sun.COM * providerType - type of provider for which to retrieve data. 36267836SJohn.Forte@Sun.COM * STMF_LU_PROVIDER_TYPE 36277836SJohn.Forte@Sun.COM * STMF_PORT_PROVIDER_TYPE 36287836SJohn.Forte@Sun.COM * setToken - Returns the stale data token 36297836SJohn.Forte@Sun.COM */ 36307836SJohn.Forte@Sun.COM int 36317836SJohn.Forte@Sun.COM stmfGetProviderDataProt(char *providerName, nvlist_t **nvl, int providerType, 36327836SJohn.Forte@Sun.COM uint64_t *setToken) 36337836SJohn.Forte@Sun.COM { 36347836SJohn.Forte@Sun.COM int ret; 36357836SJohn.Forte@Sun.COM 36367836SJohn.Forte@Sun.COM if (providerName == NULL || nvl == NULL) { 36377836SJohn.Forte@Sun.COM return (STMF_ERROR_INVALID_ARG); 36387836SJohn.Forte@Sun.COM } 36397836SJohn.Forte@Sun.COM if (providerType != STMF_LU_PROVIDER_TYPE && 36407836SJohn.Forte@Sun.COM providerType != STMF_PORT_PROVIDER_TYPE) { 36417836SJohn.Forte@Sun.COM return (STMF_ERROR_INVALID_ARG); 36427836SJohn.Forte@Sun.COM } 36437836SJohn.Forte@Sun.COM /* call init */ 36447836SJohn.Forte@Sun.COM ret = initializeConfig(); 36457836SJohn.Forte@Sun.COM if (ret != STMF_STATUS_SUCCESS) { 36467836SJohn.Forte@Sun.COM return (ret); 36477836SJohn.Forte@Sun.COM } 36489585STim.Szeto@Sun.COM return (getProviderData(providerName, nvl, providerType, setToken)); 36497836SJohn.Forte@Sun.COM } 36507836SJohn.Forte@Sun.COM 36517836SJohn.Forte@Sun.COM /* 36527836SJohn.Forte@Sun.COM * stmfGetProviderDataList 36537836SJohn.Forte@Sun.COM * 36547836SJohn.Forte@Sun.COM * Purpose: Get the list of providers currently persisting data 36557836SJohn.Forte@Sun.COM * 36567836SJohn.Forte@Sun.COM * providerList - pointer to pointer to an stmfProviderList structure allocated 36577836SJohn.Forte@Sun.COM * by the caller. Will contain the list of providers on success. 36587836SJohn.Forte@Sun.COM */ 36597836SJohn.Forte@Sun.COM int 36607836SJohn.Forte@Sun.COM stmfGetProviderDataList(stmfProviderList **providerList) 36617836SJohn.Forte@Sun.COM { 36627836SJohn.Forte@Sun.COM int ret; 36637836SJohn.Forte@Sun.COM 36647836SJohn.Forte@Sun.COM ret = psGetProviderDataList(providerList); 36657836SJohn.Forte@Sun.COM switch (ret) { 36667836SJohn.Forte@Sun.COM case STMF_PS_SUCCESS: 36677836SJohn.Forte@Sun.COM ret = STMF_STATUS_SUCCESS; 36687836SJohn.Forte@Sun.COM break; 36697836SJohn.Forte@Sun.COM case STMF_PS_ERROR_BUSY: 36707836SJohn.Forte@Sun.COM ret = STMF_ERROR_BUSY; 36717836SJohn.Forte@Sun.COM break; 36727836SJohn.Forte@Sun.COM case STMF_PS_ERROR_SERVICE_NOT_FOUND: 36737836SJohn.Forte@Sun.COM ret = STMF_ERROR_SERVICE_NOT_FOUND; 36747836SJohn.Forte@Sun.COM break; 36757836SJohn.Forte@Sun.COM case STMF_PS_ERROR_VERSION_MISMATCH: 36767836SJohn.Forte@Sun.COM ret = STMF_ERROR_SERVICE_DATA_VERSION; 36777836SJohn.Forte@Sun.COM break; 36787836SJohn.Forte@Sun.COM default: 36797836SJohn.Forte@Sun.COM syslog(LOG_DEBUG, 36807836SJohn.Forte@Sun.COM "stmfGetProviderDataList:psGetProviderDataList" 36817836SJohn.Forte@Sun.COM ":error(%d)", ret); 36827836SJohn.Forte@Sun.COM ret = STMF_STATUS_ERROR; 36837836SJohn.Forte@Sun.COM break; 36847836SJohn.Forte@Sun.COM } 36857836SJohn.Forte@Sun.COM 36867836SJohn.Forte@Sun.COM return (ret); 36877836SJohn.Forte@Sun.COM } 36887836SJohn.Forte@Sun.COM 36897836SJohn.Forte@Sun.COM 36907836SJohn.Forte@Sun.COM /* 36917836SJohn.Forte@Sun.COM * stmfGetSessionList 36927836SJohn.Forte@Sun.COM * 36937836SJohn.Forte@Sun.COM * Purpose: Retrieves the session list for a target (devid) 36947836SJohn.Forte@Sun.COM * 36957836SJohn.Forte@Sun.COM * devid - devid of target for which to retrieve session information. 36967836SJohn.Forte@Sun.COM * sessionList - pointer to pointer to stmfSessionList structure 36977836SJohn.Forte@Sun.COM * on success, this contains the list of initiator sessions. 36987836SJohn.Forte@Sun.COM */ 36997836SJohn.Forte@Sun.COM int 37007836SJohn.Forte@Sun.COM stmfGetSessionList(stmfDevid *devid, stmfSessionList **sessionList) 37017836SJohn.Forte@Sun.COM { 37027836SJohn.Forte@Sun.COM int ret = STMF_STATUS_SUCCESS; 37037836SJohn.Forte@Sun.COM int fd; 37047836SJohn.Forte@Sun.COM int ioctlRet; 37057836SJohn.Forte@Sun.COM int cmd = STMF_IOCTL_SESSION_LIST; 37067836SJohn.Forte@Sun.COM int i; 37077836SJohn.Forte@Sun.COM stmf_iocdata_t stmfIoctl; 370810261SCharles.Ting@Sun.COM slist_scsi_session_t *fSessionList, *fSessionListP = NULL; 37097836SJohn.Forte@Sun.COM uint8_t ident[260]; 37107836SJohn.Forte@Sun.COM uint32_t fSessionListSize; 37117836SJohn.Forte@Sun.COM 37127836SJohn.Forte@Sun.COM if (sessionList == NULL || devid == NULL) { 37137836SJohn.Forte@Sun.COM ret = STMF_ERROR_INVALID_ARG; 37147836SJohn.Forte@Sun.COM } 37157836SJohn.Forte@Sun.COM 37167836SJohn.Forte@Sun.COM /* call init */ 37177836SJohn.Forte@Sun.COM ret = initializeConfig(); 37187836SJohn.Forte@Sun.COM if (ret != STMF_STATUS_SUCCESS) { 37197836SJohn.Forte@Sun.COM return (ret); 37207836SJohn.Forte@Sun.COM } 37217836SJohn.Forte@Sun.COM 37227836SJohn.Forte@Sun.COM /* 37237836SJohn.Forte@Sun.COM * Open control node for stmf 37247836SJohn.Forte@Sun.COM */ 37257836SJohn.Forte@Sun.COM if ((ret = openStmf(OPEN_STMF, &fd)) != STMF_STATUS_SUCCESS) 37267836SJohn.Forte@Sun.COM return (ret); 37277836SJohn.Forte@Sun.COM 37287836SJohn.Forte@Sun.COM /* 37297836SJohn.Forte@Sun.COM * Allocate ioctl input buffer 37307836SJohn.Forte@Sun.COM */ 37319585STim.Szeto@Sun.COM fSessionListSize = ALLOC_SESSION; 37327836SJohn.Forte@Sun.COM fSessionListSize = fSessionListSize * (sizeof (slist_scsi_session_t)); 37337836SJohn.Forte@Sun.COM fSessionList = (slist_scsi_session_t *)calloc(1, fSessionListSize); 373410261SCharles.Ting@Sun.COM fSessionListP = fSessionList; 37357836SJohn.Forte@Sun.COM if (fSessionList == NULL) { 373610261SCharles.Ting@Sun.COM ret = STMF_ERROR_NOMEM; 373710261SCharles.Ting@Sun.COM goto done; 37387836SJohn.Forte@Sun.COM } 37397836SJohn.Forte@Sun.COM 37407836SJohn.Forte@Sun.COM ident[IDENT_LENGTH_BYTE] = devid->identLength; 37417836SJohn.Forte@Sun.COM bcopy(&(devid->ident), &ident[IDENT_LENGTH_BYTE + 1], 37427836SJohn.Forte@Sun.COM devid->identLength); 37437836SJohn.Forte@Sun.COM 37447836SJohn.Forte@Sun.COM bzero(&stmfIoctl, sizeof (stmfIoctl)); 37457836SJohn.Forte@Sun.COM /* 37467836SJohn.Forte@Sun.COM * Issue ioctl to get the session list 37477836SJohn.Forte@Sun.COM */ 37487836SJohn.Forte@Sun.COM stmfIoctl.stmf_version = STMF_VERSION_1; 37497836SJohn.Forte@Sun.COM stmfIoctl.stmf_ibuf = (uint64_t)(unsigned long)&ident; 37507836SJohn.Forte@Sun.COM stmfIoctl.stmf_ibuf_size = sizeof (ident); 37517836SJohn.Forte@Sun.COM stmfIoctl.stmf_obuf_size = fSessionListSize; 37527836SJohn.Forte@Sun.COM stmfIoctl.stmf_obuf = (uint64_t)(unsigned long)fSessionList; 37537836SJohn.Forte@Sun.COM ioctlRet = ioctl(fd, cmd, &stmfIoctl); 37547836SJohn.Forte@Sun.COM if (ioctlRet != 0) { 37557836SJohn.Forte@Sun.COM switch (errno) { 37567836SJohn.Forte@Sun.COM case EBUSY: 37577836SJohn.Forte@Sun.COM ret = STMF_ERROR_BUSY; 37587836SJohn.Forte@Sun.COM break; 37599585STim.Szeto@Sun.COM case EPERM: 37607836SJohn.Forte@Sun.COM case EACCES: 37617836SJohn.Forte@Sun.COM ret = STMF_ERROR_PERM; 37627836SJohn.Forte@Sun.COM break; 37637836SJohn.Forte@Sun.COM default: 37647836SJohn.Forte@Sun.COM syslog(LOG_DEBUG, 37657836SJohn.Forte@Sun.COM "stmfGetSessionList:ioctl errno(%d)", 37667836SJohn.Forte@Sun.COM errno); 37677836SJohn.Forte@Sun.COM ret = STMF_STATUS_ERROR; 37687836SJohn.Forte@Sun.COM break; 37697836SJohn.Forte@Sun.COM } 37707836SJohn.Forte@Sun.COM goto done; 37717836SJohn.Forte@Sun.COM } 37727836SJohn.Forte@Sun.COM /* 37737836SJohn.Forte@Sun.COM * Check whether input buffer was large enough 37747836SJohn.Forte@Sun.COM */ 37759585STim.Szeto@Sun.COM if (stmfIoctl.stmf_obuf_max_nentries > ALLOC_SESSION) { 37767836SJohn.Forte@Sun.COM fSessionListSize = stmfIoctl.stmf_obuf_max_nentries * 37777836SJohn.Forte@Sun.COM sizeof (slist_scsi_session_t); 37787836SJohn.Forte@Sun.COM fSessionList = realloc(fSessionList, fSessionListSize); 37797836SJohn.Forte@Sun.COM if (fSessionList == NULL) { 378010261SCharles.Ting@Sun.COM ret = STMF_ERROR_NOMEM; 378110261SCharles.Ting@Sun.COM goto done; 37827836SJohn.Forte@Sun.COM } 378310261SCharles.Ting@Sun.COM fSessionListP = fSessionList; 37847836SJohn.Forte@Sun.COM stmfIoctl.stmf_obuf_size = fSessionListSize; 37857836SJohn.Forte@Sun.COM stmfIoctl.stmf_obuf = (uint64_t)(unsigned long)fSessionList; 37867836SJohn.Forte@Sun.COM ioctlRet = ioctl(fd, cmd, &stmfIoctl); 37877836SJohn.Forte@Sun.COM if (ioctlRet != 0) { 37887836SJohn.Forte@Sun.COM switch (errno) { 37897836SJohn.Forte@Sun.COM case EBUSY: 37907836SJohn.Forte@Sun.COM ret = STMF_ERROR_BUSY; 37917836SJohn.Forte@Sun.COM break; 37929585STim.Szeto@Sun.COM case EPERM: 37937836SJohn.Forte@Sun.COM case EACCES: 37947836SJohn.Forte@Sun.COM ret = STMF_ERROR_PERM; 37957836SJohn.Forte@Sun.COM break; 37967836SJohn.Forte@Sun.COM default: 37977836SJohn.Forte@Sun.COM syslog(LOG_DEBUG, 37987836SJohn.Forte@Sun.COM "stmfGetSessionList:ioctl " 37997836SJohn.Forte@Sun.COM "errno(%d)", errno); 38007836SJohn.Forte@Sun.COM ret = STMF_STATUS_ERROR; 38017836SJohn.Forte@Sun.COM break; 38027836SJohn.Forte@Sun.COM } 38037836SJohn.Forte@Sun.COM goto done; 38047836SJohn.Forte@Sun.COM } 38057836SJohn.Forte@Sun.COM } 38067836SJohn.Forte@Sun.COM 38077836SJohn.Forte@Sun.COM /* 38087836SJohn.Forte@Sun.COM * allocate caller's buffer with the final size 38097836SJohn.Forte@Sun.COM */ 38107836SJohn.Forte@Sun.COM *sessionList = (stmfSessionList *)calloc(1, sizeof (stmfSessionList) + 38117836SJohn.Forte@Sun.COM stmfIoctl.stmf_obuf_max_nentries * sizeof (stmfSession)); 38127836SJohn.Forte@Sun.COM if (*sessionList == NULL) { 38137836SJohn.Forte@Sun.COM ret = STMF_ERROR_NOMEM; 38147836SJohn.Forte@Sun.COM free(sessionList); 38157836SJohn.Forte@Sun.COM goto done; 38167836SJohn.Forte@Sun.COM } 38177836SJohn.Forte@Sun.COM 38187836SJohn.Forte@Sun.COM (*sessionList)->cnt = stmfIoctl.stmf_obuf_max_nentries; 38197836SJohn.Forte@Sun.COM 38207836SJohn.Forte@Sun.COM /* 38217836SJohn.Forte@Sun.COM * copy session info to caller's buffer 38227836SJohn.Forte@Sun.COM */ 38237836SJohn.Forte@Sun.COM for (i = 0; i < (*sessionList)->cnt; i++) { 38247836SJohn.Forte@Sun.COM (*sessionList)->session[i].initiator.identLength = 38257836SJohn.Forte@Sun.COM fSessionList->initiator[IDENT_LENGTH_BYTE]; 38267836SJohn.Forte@Sun.COM bcopy(&(fSessionList->initiator[IDENT_LENGTH_BYTE + 1]), 38277836SJohn.Forte@Sun.COM (*sessionList)->session[i].initiator.ident, 38287836SJohn.Forte@Sun.COM STMF_IDENT_LENGTH); 38297836SJohn.Forte@Sun.COM bcopy(&(fSessionList->alias), 38307836SJohn.Forte@Sun.COM &((*sessionList)->session[i].alias), 38317836SJohn.Forte@Sun.COM sizeof ((*sessionList)->session[i].alias)); 38327836SJohn.Forte@Sun.COM bcopy(&(fSessionList++->creation_time), 38337836SJohn.Forte@Sun.COM &((*sessionList)->session[i].creationTime), 38347836SJohn.Forte@Sun.COM sizeof (time_t)); 38357836SJohn.Forte@Sun.COM } 38367836SJohn.Forte@Sun.COM done: 38377836SJohn.Forte@Sun.COM (void) close(fd); 383810261SCharles.Ting@Sun.COM free(fSessionListP); 38397836SJohn.Forte@Sun.COM return (ret); 38407836SJohn.Forte@Sun.COM } 38417836SJohn.Forte@Sun.COM 38427836SJohn.Forte@Sun.COM /* 38437836SJohn.Forte@Sun.COM * stmfGetTargetGroupList 38447836SJohn.Forte@Sun.COM * 38457836SJohn.Forte@Sun.COM * Purpose: Retrieves the list of target groups 38467836SJohn.Forte@Sun.COM * 38477836SJohn.Forte@Sun.COM * targetGroupList - pointer to a pointer to an stmfGroupList structure. On 38487836SJohn.Forte@Sun.COM * success, it contains the list of target groups. 38497836SJohn.Forte@Sun.COM */ 38507836SJohn.Forte@Sun.COM int 38517836SJohn.Forte@Sun.COM stmfGetTargetGroupList(stmfGroupList **targetGroupList) 38527836SJohn.Forte@Sun.COM { 38537836SJohn.Forte@Sun.COM int ret; 38547836SJohn.Forte@Sun.COM 38557836SJohn.Forte@Sun.COM if (targetGroupList == NULL) { 38567836SJohn.Forte@Sun.COM return (STMF_ERROR_INVALID_ARG); 38577836SJohn.Forte@Sun.COM } 38587836SJohn.Forte@Sun.COM 38599585STim.Szeto@Sun.COM ret = groupListIoctl(targetGroupList, TARGET_GROUP); 38607836SJohn.Forte@Sun.COM return (ret); 38617836SJohn.Forte@Sun.COM } 38627836SJohn.Forte@Sun.COM 38637836SJohn.Forte@Sun.COM /* 38647836SJohn.Forte@Sun.COM * stmfGetTargetGroupMembers 38657836SJohn.Forte@Sun.COM * 38667836SJohn.Forte@Sun.COM * Purpose: Retrieves the group members for a target group 38677836SJohn.Forte@Sun.COM * 38687836SJohn.Forte@Sun.COM * groupName - name of target group for which to retrieve members. 38697836SJohn.Forte@Sun.COM * groupProp - pointer to pointer to stmfGroupProperties structure 38707836SJohn.Forte@Sun.COM * on success, this contains the list of group members. 38717836SJohn.Forte@Sun.COM */ 38727836SJohn.Forte@Sun.COM int 38737836SJohn.Forte@Sun.COM stmfGetTargetGroupMembers(stmfGroupName *groupName, 38747836SJohn.Forte@Sun.COM stmfGroupProperties **groupProp) 38757836SJohn.Forte@Sun.COM { 38767836SJohn.Forte@Sun.COM int ret; 38777836SJohn.Forte@Sun.COM 38787836SJohn.Forte@Sun.COM if (groupName == NULL || groupProp == NULL) { 38797836SJohn.Forte@Sun.COM return (STMF_ERROR_INVALID_ARG); 38807836SJohn.Forte@Sun.COM } 38817836SJohn.Forte@Sun.COM 38829585STim.Szeto@Sun.COM ret = groupMemberListIoctl(groupName, groupProp, TARGET_GROUP); 38837836SJohn.Forte@Sun.COM 38847836SJohn.Forte@Sun.COM return (ret); 38857836SJohn.Forte@Sun.COM } 38867836SJohn.Forte@Sun.COM 38877836SJohn.Forte@Sun.COM /* 38887836SJohn.Forte@Sun.COM * stmfGetTargetList 38897836SJohn.Forte@Sun.COM * 38907836SJohn.Forte@Sun.COM * Purpose: Retrieves the list of target ports 38917836SJohn.Forte@Sun.COM * 38927836SJohn.Forte@Sun.COM * targetList - pointer to a pointer to an stmfDevidList structure. 38937836SJohn.Forte@Sun.COM * On success, it contains the list of local ports (target). 38947836SJohn.Forte@Sun.COM */ 38957836SJohn.Forte@Sun.COM int 38967836SJohn.Forte@Sun.COM stmfGetTargetList(stmfDevidList **targetList) 38977836SJohn.Forte@Sun.COM { 38987836SJohn.Forte@Sun.COM int ret; 38997836SJohn.Forte@Sun.COM int fd; 39007836SJohn.Forte@Sun.COM int ioctlRet; 39017836SJohn.Forte@Sun.COM int i; 39027836SJohn.Forte@Sun.COM stmf_iocdata_t stmfIoctl; 39037836SJohn.Forte@Sun.COM /* framework target port list */ 39049585STim.Szeto@Sun.COM slist_target_port_t *fTargetList, *fTargetListP = NULL; 39057836SJohn.Forte@Sun.COM uint32_t fTargetListSize; 39067836SJohn.Forte@Sun.COM 39077836SJohn.Forte@Sun.COM if (targetList == NULL) { 39087836SJohn.Forte@Sun.COM return (STMF_ERROR_INVALID_ARG); 39097836SJohn.Forte@Sun.COM } 39107836SJohn.Forte@Sun.COM 39117836SJohn.Forte@Sun.COM /* call init */ 39127836SJohn.Forte@Sun.COM ret = initializeConfig(); 39137836SJohn.Forte@Sun.COM if (ret != STMF_STATUS_SUCCESS) { 39147836SJohn.Forte@Sun.COM return (ret); 39157836SJohn.Forte@Sun.COM } 39167836SJohn.Forte@Sun.COM 39177836SJohn.Forte@Sun.COM /* 39187836SJohn.Forte@Sun.COM * Open control node for stmf 39197836SJohn.Forte@Sun.COM */ 39207836SJohn.Forte@Sun.COM if ((ret = openStmf(OPEN_STMF, &fd)) != STMF_STATUS_SUCCESS) 39217836SJohn.Forte@Sun.COM return (ret); 39227836SJohn.Forte@Sun.COM 39237836SJohn.Forte@Sun.COM /* 39247836SJohn.Forte@Sun.COM * Allocate ioctl input buffer 39257836SJohn.Forte@Sun.COM */ 39269585STim.Szeto@Sun.COM fTargetListSize = ALLOC_TARGET_PORT * sizeof (slist_target_port_t); 39278252SJohn.Forte@Sun.COM fTargetListP = fTargetList = 39288252SJohn.Forte@Sun.COM (slist_target_port_t *)calloc(1, fTargetListSize); 39297836SJohn.Forte@Sun.COM if (fTargetList == NULL) { 39309585STim.Szeto@Sun.COM ret = STMF_ERROR_NOMEM; 39317836SJohn.Forte@Sun.COM goto done; 39327836SJohn.Forte@Sun.COM } 39337836SJohn.Forte@Sun.COM 39347836SJohn.Forte@Sun.COM bzero(&stmfIoctl, sizeof (stmfIoctl)); 39357836SJohn.Forte@Sun.COM /* 39368252SJohn.Forte@Sun.COM * Issue ioctl to retrieve target list 39377836SJohn.Forte@Sun.COM */ 39387836SJohn.Forte@Sun.COM stmfIoctl.stmf_version = STMF_VERSION_1; 39397836SJohn.Forte@Sun.COM stmfIoctl.stmf_obuf_size = fTargetListSize; 39407836SJohn.Forte@Sun.COM stmfIoctl.stmf_obuf = (uint64_t)(unsigned long)fTargetList; 39417836SJohn.Forte@Sun.COM ioctlRet = ioctl(fd, STMF_IOCTL_TARGET_PORT_LIST, &stmfIoctl); 39427836SJohn.Forte@Sun.COM if (ioctlRet != 0) { 39437836SJohn.Forte@Sun.COM switch (errno) { 39447836SJohn.Forte@Sun.COM case EBUSY: 39457836SJohn.Forte@Sun.COM ret = STMF_ERROR_BUSY; 39467836SJohn.Forte@Sun.COM break; 39479585STim.Szeto@Sun.COM case EPERM: 39487836SJohn.Forte@Sun.COM case EACCES: 39497836SJohn.Forte@Sun.COM ret = STMF_ERROR_PERM; 39507836SJohn.Forte@Sun.COM break; 39517836SJohn.Forte@Sun.COM default: 39527836SJohn.Forte@Sun.COM syslog(LOG_DEBUG, 39537836SJohn.Forte@Sun.COM "stmfGetTargetList:ioctl errno(%d)", errno); 39547836SJohn.Forte@Sun.COM ret = STMF_STATUS_ERROR; 39557836SJohn.Forte@Sun.COM break; 39567836SJohn.Forte@Sun.COM } 39577836SJohn.Forte@Sun.COM goto done; 39587836SJohn.Forte@Sun.COM } 39597836SJohn.Forte@Sun.COM /* 39607836SJohn.Forte@Sun.COM * Check whether input buffer was large enough 39617836SJohn.Forte@Sun.COM */ 39629585STim.Szeto@Sun.COM if (stmfIoctl.stmf_obuf_max_nentries > ALLOC_TARGET_PORT) { 39637836SJohn.Forte@Sun.COM fTargetListSize = stmfIoctl.stmf_obuf_max_nentries * 39648116SJohn.Forte@Sun.COM sizeof (slist_target_port_t); 39658252SJohn.Forte@Sun.COM fTargetListP = fTargetList = 39668252SJohn.Forte@Sun.COM realloc(fTargetList, fTargetListSize); 39677836SJohn.Forte@Sun.COM if (fTargetList == NULL) { 39689585STim.Szeto@Sun.COM ret = STMF_ERROR_NOMEM; 39699585STim.Szeto@Sun.COM goto done; 39707836SJohn.Forte@Sun.COM } 39717836SJohn.Forte@Sun.COM stmfIoctl.stmf_obuf_size = fTargetListSize; 39727836SJohn.Forte@Sun.COM stmfIoctl.stmf_obuf = (uint64_t)(unsigned long)fTargetList; 39737836SJohn.Forte@Sun.COM ioctlRet = ioctl(fd, STMF_IOCTL_TARGET_PORT_LIST, 39747836SJohn.Forte@Sun.COM &stmfIoctl); 39757836SJohn.Forte@Sun.COM if (ioctlRet != 0) { 39767836SJohn.Forte@Sun.COM switch (errno) { 39777836SJohn.Forte@Sun.COM case EBUSY: 39787836SJohn.Forte@Sun.COM ret = STMF_ERROR_BUSY; 39797836SJohn.Forte@Sun.COM break; 39809585STim.Szeto@Sun.COM case EPERM: 39817836SJohn.Forte@Sun.COM case EACCES: 39827836SJohn.Forte@Sun.COM ret = STMF_ERROR_PERM; 39837836SJohn.Forte@Sun.COM break; 39847836SJohn.Forte@Sun.COM default: 39857836SJohn.Forte@Sun.COM syslog(LOG_DEBUG, 39867836SJohn.Forte@Sun.COM "stmfGetTargetList:ioctl errno(%d)", 39877836SJohn.Forte@Sun.COM errno); 39887836SJohn.Forte@Sun.COM ret = STMF_STATUS_ERROR; 39897836SJohn.Forte@Sun.COM break; 39907836SJohn.Forte@Sun.COM } 39917836SJohn.Forte@Sun.COM goto done; 39927836SJohn.Forte@Sun.COM } 39937836SJohn.Forte@Sun.COM } 39947836SJohn.Forte@Sun.COM 39957836SJohn.Forte@Sun.COM *targetList = (stmfDevidList *)calloc(1, 39967836SJohn.Forte@Sun.COM stmfIoctl.stmf_obuf_max_nentries * sizeof (stmfDevid) + 39977836SJohn.Forte@Sun.COM sizeof (stmfDevidList)); 39989585STim.Szeto@Sun.COM if (*targetList == NULL) { 39999585STim.Szeto@Sun.COM ret = STMF_ERROR_NOMEM; 40009585STim.Szeto@Sun.COM goto done; 40019585STim.Szeto@Sun.COM } 40027836SJohn.Forte@Sun.COM 40037836SJohn.Forte@Sun.COM (*targetList)->cnt = stmfIoctl.stmf_obuf_max_nentries; 40047836SJohn.Forte@Sun.COM for (i = 0; i < stmfIoctl.stmf_obuf_max_nentries; i++, fTargetList++) { 40057836SJohn.Forte@Sun.COM (*targetList)->devid[i].identLength = 40067836SJohn.Forte@Sun.COM fTargetList->target[IDENT_LENGTH_BYTE]; 40077836SJohn.Forte@Sun.COM bcopy(&fTargetList->target[IDENT_LENGTH_BYTE + 1], 40087836SJohn.Forte@Sun.COM &(*targetList)->devid[i].ident, 40097836SJohn.Forte@Sun.COM fTargetList->target[IDENT_LENGTH_BYTE]); 40107836SJohn.Forte@Sun.COM } 40117836SJohn.Forte@Sun.COM 40127836SJohn.Forte@Sun.COM done: 40137836SJohn.Forte@Sun.COM (void) close(fd); 40148252SJohn.Forte@Sun.COM free(fTargetListP); 40157836SJohn.Forte@Sun.COM return (ret); 40167836SJohn.Forte@Sun.COM } 40177836SJohn.Forte@Sun.COM 40187836SJohn.Forte@Sun.COM /* 40197836SJohn.Forte@Sun.COM * stmfGetTargetProperties 40207836SJohn.Forte@Sun.COM * 40217836SJohn.Forte@Sun.COM * Purpose: Retrieves the properties for a logical unit 40227836SJohn.Forte@Sun.COM * 40237836SJohn.Forte@Sun.COM * devid - devid of the target for which to retrieve properties 40247836SJohn.Forte@Sun.COM * targetProps - pointer to an stmfTargetProperties structure. 40257836SJohn.Forte@Sun.COM * On success, it contains the target properties for 40267836SJohn.Forte@Sun.COM * the specified devid. 40277836SJohn.Forte@Sun.COM */ 40287836SJohn.Forte@Sun.COM int 40297836SJohn.Forte@Sun.COM stmfGetTargetProperties(stmfDevid *devid, stmfTargetProperties *targetProps) 40307836SJohn.Forte@Sun.COM { 40317836SJohn.Forte@Sun.COM int ret = STMF_STATUS_SUCCESS; 40327836SJohn.Forte@Sun.COM int fd; 40337836SJohn.Forte@Sun.COM int ioctlRet; 40347836SJohn.Forte@Sun.COM stmf_iocdata_t stmfIoctl; 40357836SJohn.Forte@Sun.COM sioc_target_port_props_t targetProperties; 4036*10725SJohn.Forte@Sun.COM scsi_devid_desc_t *scsiDevid; 40377836SJohn.Forte@Sun.COM 40387836SJohn.Forte@Sun.COM if (devid == NULL || targetProps == NULL) { 40397836SJohn.Forte@Sun.COM return (STMF_ERROR_INVALID_ARG); 40407836SJohn.Forte@Sun.COM } 40417836SJohn.Forte@Sun.COM 40427836SJohn.Forte@Sun.COM /* call init */ 40437836SJohn.Forte@Sun.COM ret = initializeConfig(); 40447836SJohn.Forte@Sun.COM if (ret != STMF_STATUS_SUCCESS) { 40457836SJohn.Forte@Sun.COM return (ret); 40467836SJohn.Forte@Sun.COM } 40477836SJohn.Forte@Sun.COM 40487836SJohn.Forte@Sun.COM /* 40497836SJohn.Forte@Sun.COM * Open control node for stmf 40507836SJohn.Forte@Sun.COM */ 40517836SJohn.Forte@Sun.COM if ((ret = openStmf(OPEN_STMF, &fd)) != STMF_STATUS_SUCCESS) 40527836SJohn.Forte@Sun.COM return (ret); 40537836SJohn.Forte@Sun.COM 40547836SJohn.Forte@Sun.COM targetProperties.tgt_id[IDENT_LENGTH_BYTE] = devid->identLength; 40557836SJohn.Forte@Sun.COM bcopy(&(devid->ident), &targetProperties.tgt_id[IDENT_LENGTH_BYTE + 1], 40567836SJohn.Forte@Sun.COM devid->identLength); 40577836SJohn.Forte@Sun.COM 40587836SJohn.Forte@Sun.COM bzero(&stmfIoctl, sizeof (stmfIoctl)); 40597836SJohn.Forte@Sun.COM /* 40607836SJohn.Forte@Sun.COM * Issue ioctl to add to the host group 40617836SJohn.Forte@Sun.COM */ 40627836SJohn.Forte@Sun.COM stmfIoctl.stmf_version = STMF_VERSION_1; 40637836SJohn.Forte@Sun.COM stmfIoctl.stmf_ibuf_size = sizeof (targetProperties.tgt_id); 40647836SJohn.Forte@Sun.COM stmfIoctl.stmf_ibuf = (uint64_t)(unsigned long)&targetProperties.tgt_id; 40657836SJohn.Forte@Sun.COM stmfIoctl.stmf_obuf = (uint64_t)(unsigned long)&targetProperties; 40667836SJohn.Forte@Sun.COM stmfIoctl.stmf_obuf_size = sizeof (targetProperties); 40677836SJohn.Forte@Sun.COM ioctlRet = ioctl(fd, STMF_IOCTL_GET_TARGET_PORT_PROPERTIES, 40687836SJohn.Forte@Sun.COM &stmfIoctl); 40697836SJohn.Forte@Sun.COM if (ioctlRet != 0) { 40707836SJohn.Forte@Sun.COM switch (errno) { 40717836SJohn.Forte@Sun.COM case EBUSY: 40727836SJohn.Forte@Sun.COM ret = STMF_ERROR_BUSY; 40737836SJohn.Forte@Sun.COM break; 40749585STim.Szeto@Sun.COM case EPERM: 40757836SJohn.Forte@Sun.COM case EACCES: 40767836SJohn.Forte@Sun.COM ret = STMF_ERROR_PERM; 40777836SJohn.Forte@Sun.COM break; 40787836SJohn.Forte@Sun.COM case ENOENT: 40797836SJohn.Forte@Sun.COM ret = STMF_ERROR_NOT_FOUND; 40807836SJohn.Forte@Sun.COM break; 40817836SJohn.Forte@Sun.COM default: 40827836SJohn.Forte@Sun.COM syslog(LOG_DEBUG, 40837836SJohn.Forte@Sun.COM "stmfGetTargetProperties:ioctl errno(%d)", 40847836SJohn.Forte@Sun.COM errno); 40857836SJohn.Forte@Sun.COM ret = STMF_STATUS_ERROR; 40867836SJohn.Forte@Sun.COM break; 40877836SJohn.Forte@Sun.COM } 40887836SJohn.Forte@Sun.COM goto done; 40897836SJohn.Forte@Sun.COM } 40907836SJohn.Forte@Sun.COM 40917836SJohn.Forte@Sun.COM bcopy(targetProperties.tgt_provider_name, targetProps->providerName, 40927836SJohn.Forte@Sun.COM sizeof (targetProperties.tgt_provider_name)); 40937836SJohn.Forte@Sun.COM if (targetProperties.tgt_state == STMF_STATE_ONLINE) { 40947836SJohn.Forte@Sun.COM targetProps->status = STMF_TARGET_PORT_ONLINE; 40957836SJohn.Forte@Sun.COM } else if (targetProperties.tgt_state == STMF_STATE_OFFLINE) { 40967836SJohn.Forte@Sun.COM targetProps->status = STMF_TARGET_PORT_OFFLINE; 40977836SJohn.Forte@Sun.COM } else if (targetProperties.tgt_state == STMF_STATE_ONLINING) { 40987836SJohn.Forte@Sun.COM targetProps->status = STMF_TARGET_PORT_ONLINING; 40997836SJohn.Forte@Sun.COM } else if (targetProperties.tgt_state == STMF_STATE_OFFLINING) { 41007836SJohn.Forte@Sun.COM targetProps->status = STMF_TARGET_PORT_OFFLINING; 41017836SJohn.Forte@Sun.COM } 41027836SJohn.Forte@Sun.COM bcopy(targetProperties.tgt_alias, targetProps->alias, 41037836SJohn.Forte@Sun.COM sizeof (targetProps->alias)); 4104*10725SJohn.Forte@Sun.COM 4105*10725SJohn.Forte@Sun.COM scsiDevid = (scsi_devid_desc_t *)&targetProperties.tgt_id; 4106*10725SJohn.Forte@Sun.COM targetProps->protocol = scsiDevid->protocol_id; 4107*10725SJohn.Forte@Sun.COM 41087836SJohn.Forte@Sun.COM done: 41097836SJohn.Forte@Sun.COM (void) close(fd); 41107836SJohn.Forte@Sun.COM return (ret); 41117836SJohn.Forte@Sun.COM } 41127836SJohn.Forte@Sun.COM 41137836SJohn.Forte@Sun.COM /* 41147836SJohn.Forte@Sun.COM * stmfGetLogicalUnitList 41157836SJohn.Forte@Sun.COM * 41167836SJohn.Forte@Sun.COM * Purpose: Retrieves list of logical unit Object IDs 41177836SJohn.Forte@Sun.COM * 41187836SJohn.Forte@Sun.COM * luList - pointer to a pointer to a stmfGuidList structure. On success, 41197836SJohn.Forte@Sun.COM * it contains the list of logical unit guids. 41207836SJohn.Forte@Sun.COM * 41217836SJohn.Forte@Sun.COM */ 41227836SJohn.Forte@Sun.COM int 41237836SJohn.Forte@Sun.COM stmfGetLogicalUnitList(stmfGuidList **luList) 41247836SJohn.Forte@Sun.COM { 41257836SJohn.Forte@Sun.COM int ret; 41267836SJohn.Forte@Sun.COM int fd; 41277836SJohn.Forte@Sun.COM int ioctlRet; 41287836SJohn.Forte@Sun.COM int cmd = STMF_IOCTL_LU_LIST; 41299585STim.Szeto@Sun.COM int i; 41307836SJohn.Forte@Sun.COM stmf_iocdata_t stmfIoctl; 41317836SJohn.Forte@Sun.COM slist_lu_t *fLuList; 41327836SJohn.Forte@Sun.COM uint32_t fLuListSize; 41339585STim.Szeto@Sun.COM uint32_t listCnt; 41347836SJohn.Forte@Sun.COM 41357836SJohn.Forte@Sun.COM if (luList == NULL) { 41367836SJohn.Forte@Sun.COM return (STMF_ERROR_INVALID_ARG); 41377836SJohn.Forte@Sun.COM } 41387836SJohn.Forte@Sun.COM 41397836SJohn.Forte@Sun.COM /* call init */ 41407836SJohn.Forte@Sun.COM ret = initializeConfig(); 41417836SJohn.Forte@Sun.COM if (ret != STMF_STATUS_SUCCESS) { 41427836SJohn.Forte@Sun.COM return (ret); 41437836SJohn.Forte@Sun.COM } 41447836SJohn.Forte@Sun.COM 41457836SJohn.Forte@Sun.COM /* 41467836SJohn.Forte@Sun.COM * Open control node for stmf 41477836SJohn.Forte@Sun.COM */ 41487836SJohn.Forte@Sun.COM if ((ret = openStmf(OPEN_STMF, &fd)) != STMF_STATUS_SUCCESS) 41497836SJohn.Forte@Sun.COM return (ret); 41507836SJohn.Forte@Sun.COM 41517836SJohn.Forte@Sun.COM /* 41527836SJohn.Forte@Sun.COM * Allocate ioctl input buffer 41537836SJohn.Forte@Sun.COM */ 41549585STim.Szeto@Sun.COM fLuListSize = ALLOC_LU; 41557836SJohn.Forte@Sun.COM fLuListSize = fLuListSize * (sizeof (slist_lu_t)); 41567836SJohn.Forte@Sun.COM fLuList = (slist_lu_t *)calloc(1, fLuListSize); 41577836SJohn.Forte@Sun.COM if (fLuList == NULL) { 41589585STim.Szeto@Sun.COM ret = STMF_ERROR_NOMEM; 41599585STim.Szeto@Sun.COM goto done; 41607836SJohn.Forte@Sun.COM } 41617836SJohn.Forte@Sun.COM 41627836SJohn.Forte@Sun.COM bzero(&stmfIoctl, sizeof (stmfIoctl)); 41637836SJohn.Forte@Sun.COM /* 41647836SJohn.Forte@Sun.COM * Issue ioctl to get the LU list 41657836SJohn.Forte@Sun.COM */ 41667836SJohn.Forte@Sun.COM stmfIoctl.stmf_version = STMF_VERSION_1; 41677836SJohn.Forte@Sun.COM stmfIoctl.stmf_obuf_size = fLuListSize; 41687836SJohn.Forte@Sun.COM stmfIoctl.stmf_obuf = (uint64_t)(unsigned long)fLuList; 41697836SJohn.Forte@Sun.COM ioctlRet = ioctl(fd, cmd, &stmfIoctl); 41707836SJohn.Forte@Sun.COM if (ioctlRet != 0) { 41717836SJohn.Forte@Sun.COM switch (errno) { 41727836SJohn.Forte@Sun.COM case EBUSY: 41737836SJohn.Forte@Sun.COM ret = STMF_ERROR_BUSY; 41747836SJohn.Forte@Sun.COM break; 41759585STim.Szeto@Sun.COM case EPERM: 41767836SJohn.Forte@Sun.COM case EACCES: 41777836SJohn.Forte@Sun.COM ret = STMF_ERROR_PERM; 41787836SJohn.Forte@Sun.COM break; 41797836SJohn.Forte@Sun.COM default: 41807836SJohn.Forte@Sun.COM syslog(LOG_DEBUG, 41817836SJohn.Forte@Sun.COM "stmfGetLogicalUnitList:ioctl errno(%d)", 41827836SJohn.Forte@Sun.COM errno); 41837836SJohn.Forte@Sun.COM ret = STMF_STATUS_ERROR; 41847836SJohn.Forte@Sun.COM break; 41857836SJohn.Forte@Sun.COM } 41867836SJohn.Forte@Sun.COM goto done; 41877836SJohn.Forte@Sun.COM } 41887836SJohn.Forte@Sun.COM /* 41897836SJohn.Forte@Sun.COM * Check whether input buffer was large enough 41907836SJohn.Forte@Sun.COM */ 41919585STim.Szeto@Sun.COM if (stmfIoctl.stmf_obuf_max_nentries > ALLOC_LU) { 41927836SJohn.Forte@Sun.COM fLuListSize = stmfIoctl.stmf_obuf_max_nentries * 41937836SJohn.Forte@Sun.COM sizeof (slist_lu_t); 41949585STim.Szeto@Sun.COM free(fLuList); 41959585STim.Szeto@Sun.COM fLuList = (slist_lu_t *)calloc(1, fLuListSize); 41967836SJohn.Forte@Sun.COM if (fLuList == NULL) { 41979585STim.Szeto@Sun.COM ret = STMF_ERROR_NOMEM; 41989585STim.Szeto@Sun.COM goto done; 41997836SJohn.Forte@Sun.COM } 42007836SJohn.Forte@Sun.COM stmfIoctl.stmf_obuf_size = fLuListSize; 42017836SJohn.Forte@Sun.COM stmfIoctl.stmf_obuf = (uint64_t)(unsigned long)fLuList; 42027836SJohn.Forte@Sun.COM ioctlRet = ioctl(fd, cmd, &stmfIoctl); 42037836SJohn.Forte@Sun.COM if (ioctlRet != 0) { 42047836SJohn.Forte@Sun.COM switch (errno) { 42057836SJohn.Forte@Sun.COM case EBUSY: 42067836SJohn.Forte@Sun.COM ret = STMF_ERROR_BUSY; 42077836SJohn.Forte@Sun.COM break; 42089585STim.Szeto@Sun.COM case EPERM: 42097836SJohn.Forte@Sun.COM case EACCES: 42107836SJohn.Forte@Sun.COM ret = STMF_ERROR_PERM; 42117836SJohn.Forte@Sun.COM break; 42127836SJohn.Forte@Sun.COM default: 42137836SJohn.Forte@Sun.COM syslog(LOG_DEBUG, 42147836SJohn.Forte@Sun.COM "stmfGetLogicalUnitList:" 42157836SJohn.Forte@Sun.COM "ioctl errno(%d)", errno); 42167836SJohn.Forte@Sun.COM ret = STMF_STATUS_ERROR; 42177836SJohn.Forte@Sun.COM break; 42187836SJohn.Forte@Sun.COM } 42197836SJohn.Forte@Sun.COM goto done; 42207836SJohn.Forte@Sun.COM } 42217836SJohn.Forte@Sun.COM } 42227836SJohn.Forte@Sun.COM 42237836SJohn.Forte@Sun.COM if (ret != STMF_STATUS_SUCCESS) { 42247836SJohn.Forte@Sun.COM goto done; 42257836SJohn.Forte@Sun.COM } 42267836SJohn.Forte@Sun.COM 42279585STim.Szeto@Sun.COM listCnt = stmfIoctl.stmf_obuf_nentries; 42287836SJohn.Forte@Sun.COM 42297836SJohn.Forte@Sun.COM /* 42307836SJohn.Forte@Sun.COM * allocate caller's buffer with the final size 42317836SJohn.Forte@Sun.COM */ 42327836SJohn.Forte@Sun.COM *luList = (stmfGuidList *)calloc(1, sizeof (stmfGuidList) + 42339585STim.Szeto@Sun.COM listCnt * sizeof (stmfGuid)); 42347836SJohn.Forte@Sun.COM if (*luList == NULL) { 42357836SJohn.Forte@Sun.COM ret = STMF_ERROR_NOMEM; 42367836SJohn.Forte@Sun.COM goto done; 42377836SJohn.Forte@Sun.COM } 42387836SJohn.Forte@Sun.COM 42399585STim.Szeto@Sun.COM (*luList)->cnt = listCnt; 42409585STim.Szeto@Sun.COM 42419585STim.Szeto@Sun.COM /* copy to caller's buffer */ 42429585STim.Szeto@Sun.COM for (i = 0; i < listCnt; i++) { 42439585STim.Szeto@Sun.COM bcopy(&fLuList[i].lu_guid, (*luList)->guid[i].guid, 42449585STim.Szeto@Sun.COM sizeof (stmfGuid)); 42459585STim.Szeto@Sun.COM } 42469585STim.Szeto@Sun.COM 42477836SJohn.Forte@Sun.COM /* 42489585STim.Szeto@Sun.COM * sort the list. This gives a consistent view across gets 42497836SJohn.Forte@Sun.COM */ 42509585STim.Szeto@Sun.COM qsort((void *)&((*luList)->guid[0]), (*luList)->cnt, 42519585STim.Szeto@Sun.COM sizeof (stmfGuid), guidCompare); 42527836SJohn.Forte@Sun.COM 42537836SJohn.Forte@Sun.COM done: 42547836SJohn.Forte@Sun.COM (void) close(fd); 42557836SJohn.Forte@Sun.COM /* 42567836SJohn.Forte@Sun.COM * free internal buffers 42577836SJohn.Forte@Sun.COM */ 42587836SJohn.Forte@Sun.COM free(fLuList); 42597836SJohn.Forte@Sun.COM return (ret); 42607836SJohn.Forte@Sun.COM } 42617836SJohn.Forte@Sun.COM 42627836SJohn.Forte@Sun.COM /* 42637836SJohn.Forte@Sun.COM * stmfGetLogicalUnitProperties 42647836SJohn.Forte@Sun.COM * 42657836SJohn.Forte@Sun.COM * Purpose: Retrieves the properties for a logical unit 42667836SJohn.Forte@Sun.COM * 42677836SJohn.Forte@Sun.COM * lu - guid of the logical unit for which to retrieve properties 42687836SJohn.Forte@Sun.COM * stmfLuProps - pointer to an stmfLogicalUnitProperties structure. On success, 42697836SJohn.Forte@Sun.COM * it contains the logical unit properties for the specified guid. 42707836SJohn.Forte@Sun.COM */ 42717836SJohn.Forte@Sun.COM int 42727836SJohn.Forte@Sun.COM stmfGetLogicalUnitProperties(stmfGuid *lu, stmfLogicalUnitProperties *luProps) 42737836SJohn.Forte@Sun.COM { 42747836SJohn.Forte@Sun.COM int ret = STMF_STATUS_SUCCESS; 42757836SJohn.Forte@Sun.COM int stmfRet; 42767836SJohn.Forte@Sun.COM int fd; 42777836SJohn.Forte@Sun.COM int ioctlRet; 42787836SJohn.Forte@Sun.COM int cmd = STMF_IOCTL_GET_LU_PROPERTIES; 42797836SJohn.Forte@Sun.COM stmfViewEntryList *viewEntryList = NULL; 42807836SJohn.Forte@Sun.COM stmf_iocdata_t stmfIoctl; 42817836SJohn.Forte@Sun.COM sioc_lu_props_t fLuProps; 42827836SJohn.Forte@Sun.COM 42839585STim.Szeto@Sun.COM if (lu == NULL || luProps == NULL) { 42849585STim.Szeto@Sun.COM return (STMF_ERROR_INVALID_ARG); 42857836SJohn.Forte@Sun.COM } 42867836SJohn.Forte@Sun.COM 42877836SJohn.Forte@Sun.COM bzero(luProps, sizeof (stmfLogicalUnitProperties)); 42887836SJohn.Forte@Sun.COM 42897836SJohn.Forte@Sun.COM /* call init */ 42907836SJohn.Forte@Sun.COM ret = initializeConfig(); 42917836SJohn.Forte@Sun.COM if (ret != STMF_STATUS_SUCCESS) { 42927836SJohn.Forte@Sun.COM return (ret); 42937836SJohn.Forte@Sun.COM } 42947836SJohn.Forte@Sun.COM 42957836SJohn.Forte@Sun.COM /* 42967836SJohn.Forte@Sun.COM * Open control node for stmf 42977836SJohn.Forte@Sun.COM */ 42987836SJohn.Forte@Sun.COM if ((ret = openStmf(OPEN_STMF, &fd)) != STMF_STATUS_SUCCESS) 42997836SJohn.Forte@Sun.COM return (ret); 43007836SJohn.Forte@Sun.COM 43017836SJohn.Forte@Sun.COM bzero(&stmfIoctl, sizeof (stmfIoctl)); 43027836SJohn.Forte@Sun.COM /* 43037836SJohn.Forte@Sun.COM * Issue ioctl to add to the host group 43047836SJohn.Forte@Sun.COM */ 43057836SJohn.Forte@Sun.COM stmfIoctl.stmf_version = STMF_VERSION_1; 43067836SJohn.Forte@Sun.COM stmfIoctl.stmf_ibuf_size = sizeof (stmfGuid); 43077836SJohn.Forte@Sun.COM stmfIoctl.stmf_ibuf = (uint64_t)(unsigned long)lu; 43087836SJohn.Forte@Sun.COM stmfIoctl.stmf_obuf = (uint64_t)(unsigned long)&fLuProps; 43097836SJohn.Forte@Sun.COM stmfIoctl.stmf_obuf_size = sizeof (fLuProps); 43107836SJohn.Forte@Sun.COM ioctlRet = ioctl(fd, cmd, &stmfIoctl); 43117836SJohn.Forte@Sun.COM if (ioctlRet != 0) { 43127836SJohn.Forte@Sun.COM switch (errno) { 43137836SJohn.Forte@Sun.COM case EBUSY: 43147836SJohn.Forte@Sun.COM ret = STMF_ERROR_BUSY; 43157836SJohn.Forte@Sun.COM break; 43169585STim.Szeto@Sun.COM case EPERM: 43177836SJohn.Forte@Sun.COM case EACCES: 43187836SJohn.Forte@Sun.COM ret = STMF_ERROR_PERM; 43197836SJohn.Forte@Sun.COM break; 43207836SJohn.Forte@Sun.COM case ENOENT: 43217836SJohn.Forte@Sun.COM stmfRet = stmfGetViewEntryList(lu, 43227836SJohn.Forte@Sun.COM &viewEntryList); 43237836SJohn.Forte@Sun.COM if (stmfRet == STMF_STATUS_SUCCESS) { 43247836SJohn.Forte@Sun.COM luProps->status = 43257836SJohn.Forte@Sun.COM STMF_LOGICAL_UNIT_UNREGISTERED; 43267836SJohn.Forte@Sun.COM if (viewEntryList->cnt > 0) { 43277836SJohn.Forte@Sun.COM ret = STMF_STATUS_SUCCESS; 43287836SJohn.Forte@Sun.COM } else { 43297836SJohn.Forte@Sun.COM ret = STMF_ERROR_NOT_FOUND; 43307836SJohn.Forte@Sun.COM } 43317836SJohn.Forte@Sun.COM } else { 43327836SJohn.Forte@Sun.COM ret = STMF_ERROR_NOT_FOUND; 43337836SJohn.Forte@Sun.COM } 43347836SJohn.Forte@Sun.COM stmfFreeMemory(viewEntryList); 43357836SJohn.Forte@Sun.COM break; 43367836SJohn.Forte@Sun.COM default: 43377836SJohn.Forte@Sun.COM syslog(LOG_DEBUG, 43387836SJohn.Forte@Sun.COM "stmfGetLogicalUnit:ioctl errno(%d)", 43397836SJohn.Forte@Sun.COM errno); 43407836SJohn.Forte@Sun.COM ret = STMF_STATUS_ERROR; 43417836SJohn.Forte@Sun.COM break; 43427836SJohn.Forte@Sun.COM } 43437836SJohn.Forte@Sun.COM goto done; 43447836SJohn.Forte@Sun.COM } 43457836SJohn.Forte@Sun.COM 43467836SJohn.Forte@Sun.COM bcopy(fLuProps.lu_provider_name, luProps->providerName, 43477836SJohn.Forte@Sun.COM sizeof (fLuProps.lu_provider_name)); 43487836SJohn.Forte@Sun.COM if (fLuProps.lu_state == STMF_STATE_ONLINE) { 43497836SJohn.Forte@Sun.COM luProps->status = STMF_LOGICAL_UNIT_ONLINE; 43507836SJohn.Forte@Sun.COM } else if (fLuProps.lu_state == STMF_STATE_OFFLINE) { 43517836SJohn.Forte@Sun.COM luProps->status = STMF_LOGICAL_UNIT_OFFLINE; 43527836SJohn.Forte@Sun.COM } else if (fLuProps.lu_state == STMF_STATE_ONLINING) { 43537836SJohn.Forte@Sun.COM luProps->status = STMF_LOGICAL_UNIT_ONLINING; 43547836SJohn.Forte@Sun.COM } else if (fLuProps.lu_state == STMF_STATE_OFFLINING) { 43557836SJohn.Forte@Sun.COM luProps->status = STMF_LOGICAL_UNIT_OFFLINING; 43567836SJohn.Forte@Sun.COM } 43577836SJohn.Forte@Sun.COM bcopy(fLuProps.lu_alias, luProps->alias, sizeof (luProps->alias)); 43587836SJohn.Forte@Sun.COM done: 43597836SJohn.Forte@Sun.COM (void) close(fd); 43607836SJohn.Forte@Sun.COM return (ret); 43617836SJohn.Forte@Sun.COM } 43627836SJohn.Forte@Sun.COM 43637836SJohn.Forte@Sun.COM /* 43647836SJohn.Forte@Sun.COM * stmfGetState 43657836SJohn.Forte@Sun.COM * 43667836SJohn.Forte@Sun.COM * Purpose: retrieve the current state of the stmf module 43677836SJohn.Forte@Sun.COM * 43687836SJohn.Forte@Sun.COM * state - pointer to stmfState structure allocated by the caller 43697836SJohn.Forte@Sun.COM * On success, contains the state of stmf 43707836SJohn.Forte@Sun.COM */ 43717836SJohn.Forte@Sun.COM int 43727836SJohn.Forte@Sun.COM stmfGetState(stmfState *state) 43737836SJohn.Forte@Sun.COM { 43747836SJohn.Forte@Sun.COM int ret; 43757836SJohn.Forte@Sun.COM stmf_state_desc_t iState; 43767836SJohn.Forte@Sun.COM 43777836SJohn.Forte@Sun.COM if (state == NULL) { 43787836SJohn.Forte@Sun.COM return (STMF_ERROR_INVALID_ARG); 43797836SJohn.Forte@Sun.COM } 43807836SJohn.Forte@Sun.COM 43817836SJohn.Forte@Sun.COM ret = getStmfState(&iState); 43827836SJohn.Forte@Sun.COM if (ret != STMF_STATUS_SUCCESS) { 43837836SJohn.Forte@Sun.COM return (ret); 43847836SJohn.Forte@Sun.COM } 43857836SJohn.Forte@Sun.COM switch (iState.state) { 43867836SJohn.Forte@Sun.COM case STMF_STATE_ONLINE: 43877836SJohn.Forte@Sun.COM state->operationalState = 43887836SJohn.Forte@Sun.COM STMF_SERVICE_STATE_ONLINE; 43897836SJohn.Forte@Sun.COM break; 43907836SJohn.Forte@Sun.COM case STMF_STATE_OFFLINE: 43917836SJohn.Forte@Sun.COM state->operationalState = 43927836SJohn.Forte@Sun.COM STMF_SERVICE_STATE_OFFLINE; 43937836SJohn.Forte@Sun.COM break; 43947836SJohn.Forte@Sun.COM case STMF_STATE_ONLINING: 43957836SJohn.Forte@Sun.COM state->operationalState = 43967836SJohn.Forte@Sun.COM STMF_SERVICE_STATE_ONLINING; 43977836SJohn.Forte@Sun.COM break; 43987836SJohn.Forte@Sun.COM case STMF_STATE_OFFLINING: 43997836SJohn.Forte@Sun.COM state->operationalState = 44007836SJohn.Forte@Sun.COM STMF_SERVICE_STATE_OFFLINING; 44017836SJohn.Forte@Sun.COM break; 44027836SJohn.Forte@Sun.COM default: 44037836SJohn.Forte@Sun.COM state->operationalState = 44047836SJohn.Forte@Sun.COM STMF_SERVICE_STATE_UNKNOWN; 44057836SJohn.Forte@Sun.COM break; 44067836SJohn.Forte@Sun.COM } 44077836SJohn.Forte@Sun.COM switch (iState.config_state) { 44087836SJohn.Forte@Sun.COM case STMF_CONFIG_NONE: 44097836SJohn.Forte@Sun.COM state->configState = STMF_CONFIG_STATE_NONE; 44107836SJohn.Forte@Sun.COM break; 44117836SJohn.Forte@Sun.COM case STMF_CONFIG_INIT: 44127836SJohn.Forte@Sun.COM state->configState = STMF_CONFIG_STATE_INIT; 44137836SJohn.Forte@Sun.COM break; 44147836SJohn.Forte@Sun.COM case STMF_CONFIG_INIT_DONE: 44157836SJohn.Forte@Sun.COM state->configState = 44167836SJohn.Forte@Sun.COM STMF_CONFIG_STATE_INIT_DONE; 44177836SJohn.Forte@Sun.COM break; 44187836SJohn.Forte@Sun.COM default: 44197836SJohn.Forte@Sun.COM state->configState = 44207836SJohn.Forte@Sun.COM STMF_CONFIG_STATE_UNKNOWN; 44217836SJohn.Forte@Sun.COM break; 44227836SJohn.Forte@Sun.COM } 44237836SJohn.Forte@Sun.COM return (STMF_STATUS_SUCCESS); 44247836SJohn.Forte@Sun.COM } 44257836SJohn.Forte@Sun.COM 44267836SJohn.Forte@Sun.COM /* 44277836SJohn.Forte@Sun.COM * stmfGetViewEntryList 44287836SJohn.Forte@Sun.COM * 44297836SJohn.Forte@Sun.COM * Purpose: Retrieves the list of view entries for the specified 44307836SJohn.Forte@Sun.COM * logical unit. 44317836SJohn.Forte@Sun.COM * 44327836SJohn.Forte@Sun.COM * lu - the guid of the logical unit for which to retrieve the view entry list 44337836SJohn.Forte@Sun.COM * viewEntryList - a pointer to a pointer to a stmfViewEntryList structure. On 44347836SJohn.Forte@Sun.COM * success, contains the list of view entries. 44357836SJohn.Forte@Sun.COM */ 44367836SJohn.Forte@Sun.COM int 44377836SJohn.Forte@Sun.COM stmfGetViewEntryList(stmfGuid *lu, stmfViewEntryList **viewEntryList) 44387836SJohn.Forte@Sun.COM { 44397836SJohn.Forte@Sun.COM int ret; 44409585STim.Szeto@Sun.COM int fd; 44419585STim.Szeto@Sun.COM int ioctlRet; 44429585STim.Szeto@Sun.COM int cmd = STMF_IOCTL_LU_VE_LIST; 44439585STim.Szeto@Sun.COM int i; 44449585STim.Szeto@Sun.COM stmf_iocdata_t stmfIoctl; 44459585STim.Szeto@Sun.COM stmf_view_op_entry_t *fVeList; 44469585STim.Szeto@Sun.COM uint32_t fVeListSize; 44479585STim.Szeto@Sun.COM uint32_t listCnt; 44487836SJohn.Forte@Sun.COM 44497836SJohn.Forte@Sun.COM if (lu == NULL || viewEntryList == NULL) { 44507836SJohn.Forte@Sun.COM return (STMF_ERROR_INVALID_ARG); 44517836SJohn.Forte@Sun.COM } 44527836SJohn.Forte@Sun.COM 44539585STim.Szeto@Sun.COM /* call init */ 44549585STim.Szeto@Sun.COM ret = initializeConfig(); 44559585STim.Szeto@Sun.COM if (ret != STMF_STATUS_SUCCESS) { 44569585STim.Szeto@Sun.COM return (ret); 44579585STim.Szeto@Sun.COM } 44589585STim.Szeto@Sun.COM 44599585STim.Szeto@Sun.COM /* 44609585STim.Szeto@Sun.COM * Open control node for stmf 44619585STim.Szeto@Sun.COM */ 44629585STim.Szeto@Sun.COM if ((ret = openStmf(OPEN_STMF, &fd)) != STMF_STATUS_SUCCESS) 44639585STim.Szeto@Sun.COM return (ret); 44649585STim.Szeto@Sun.COM 44659585STim.Szeto@Sun.COM /* 44669585STim.Szeto@Sun.COM * Allocate ioctl input buffer 44679585STim.Szeto@Sun.COM */ 44689585STim.Szeto@Sun.COM fVeListSize = ALLOC_VE; 44699585STim.Szeto@Sun.COM fVeListSize = fVeListSize * (sizeof (stmf_view_op_entry_t)); 44709585STim.Szeto@Sun.COM fVeList = (stmf_view_op_entry_t *)calloc(1, fVeListSize); 44719585STim.Szeto@Sun.COM if (fVeList == NULL) { 44729585STim.Szeto@Sun.COM ret = STMF_ERROR_NOMEM; 44739585STim.Szeto@Sun.COM goto done; 44749585STim.Szeto@Sun.COM } 44759585STim.Szeto@Sun.COM 44769585STim.Szeto@Sun.COM bzero(&stmfIoctl, sizeof (stmfIoctl)); 44779585STim.Szeto@Sun.COM /* 44789585STim.Szeto@Sun.COM * Issue ioctl to get the LU list 44799585STim.Szeto@Sun.COM */ 44809585STim.Szeto@Sun.COM stmfIoctl.stmf_version = STMF_VERSION_1; 44819585STim.Szeto@Sun.COM stmfIoctl.stmf_ibuf = (uint64_t)(unsigned long)lu; 44829585STim.Szeto@Sun.COM stmfIoctl.stmf_ibuf_size = sizeof (stmfGuid); 44839585STim.Szeto@Sun.COM stmfIoctl.stmf_obuf_size = fVeListSize; 44849585STim.Szeto@Sun.COM stmfIoctl.stmf_obuf = (uint64_t)(unsigned long)fVeList; 44859585STim.Szeto@Sun.COM ioctlRet = ioctl(fd, cmd, &stmfIoctl); 44869585STim.Szeto@Sun.COM if (ioctlRet != 0) { 44879585STim.Szeto@Sun.COM switch (errno) { 44889585STim.Szeto@Sun.COM case EBUSY: 44899585STim.Szeto@Sun.COM ret = STMF_ERROR_BUSY; 44909585STim.Szeto@Sun.COM break; 44919585STim.Szeto@Sun.COM case EPERM: 44929585STim.Szeto@Sun.COM case EACCES: 44939585STim.Szeto@Sun.COM ret = STMF_ERROR_PERM; 44949585STim.Szeto@Sun.COM break; 44959585STim.Szeto@Sun.COM default: 44969585STim.Szeto@Sun.COM syslog(LOG_DEBUG, 44979585STim.Szeto@Sun.COM "stmfGetViewEntryList:ioctl errno(%d)", 44989585STim.Szeto@Sun.COM errno); 44999585STim.Szeto@Sun.COM ret = STMF_STATUS_ERROR; 45009585STim.Szeto@Sun.COM break; 45019585STim.Szeto@Sun.COM } 45029585STim.Szeto@Sun.COM goto done; 45039585STim.Szeto@Sun.COM } 45049585STim.Szeto@Sun.COM /* 45059585STim.Szeto@Sun.COM * Check whether input buffer was large enough 45069585STim.Szeto@Sun.COM */ 45079585STim.Szeto@Sun.COM if (stmfIoctl.stmf_obuf_max_nentries > ALLOC_VE) { 45089585STim.Szeto@Sun.COM bzero(&stmfIoctl, sizeof (stmfIoctl)); 45099585STim.Szeto@Sun.COM fVeListSize = stmfIoctl.stmf_obuf_max_nentries * 45109585STim.Szeto@Sun.COM sizeof (stmf_view_op_entry_t); 45119585STim.Szeto@Sun.COM free(fVeList); 45129585STim.Szeto@Sun.COM fVeList = (stmf_view_op_entry_t *)calloc(1, fVeListSize); 45139585STim.Szeto@Sun.COM if (fVeList == NULL) { 45149585STim.Szeto@Sun.COM return (STMF_ERROR_NOMEM); 45159585STim.Szeto@Sun.COM } 45169585STim.Szeto@Sun.COM stmfIoctl.stmf_obuf_size = fVeListSize; 45179585STim.Szeto@Sun.COM stmfIoctl.stmf_obuf = (uint64_t)(unsigned long)fVeList; 45189585STim.Szeto@Sun.COM ioctlRet = ioctl(fd, cmd, &stmfIoctl); 45199585STim.Szeto@Sun.COM if (ioctlRet != 0) { 45209585STim.Szeto@Sun.COM switch (errno) { 45219585STim.Szeto@Sun.COM case EBUSY: 45229585STim.Szeto@Sun.COM ret = STMF_ERROR_BUSY; 45239585STim.Szeto@Sun.COM break; 45249585STim.Szeto@Sun.COM case EPERM: 45259585STim.Szeto@Sun.COM case EACCES: 45269585STim.Szeto@Sun.COM ret = STMF_ERROR_PERM; 45279585STim.Szeto@Sun.COM break; 45289585STim.Szeto@Sun.COM default: 45299585STim.Szeto@Sun.COM syslog(LOG_DEBUG, 45309585STim.Szeto@Sun.COM "stmfGetLogicalUnitList:" 45319585STim.Szeto@Sun.COM "ioctl errno(%d)", errno); 45329585STim.Szeto@Sun.COM ret = STMF_STATUS_ERROR; 45339585STim.Szeto@Sun.COM break; 45349585STim.Szeto@Sun.COM } 45359585STim.Szeto@Sun.COM goto done; 45369585STim.Szeto@Sun.COM } 45379585STim.Szeto@Sun.COM } 45389585STim.Szeto@Sun.COM 45399585STim.Szeto@Sun.COM if (ret != STMF_STATUS_SUCCESS) { 45409585STim.Szeto@Sun.COM goto done; 45419585STim.Szeto@Sun.COM } 45429585STim.Szeto@Sun.COM 45439585STim.Szeto@Sun.COM if (stmfIoctl.stmf_obuf_nentries == 0) { 45449585STim.Szeto@Sun.COM ret = STMF_ERROR_NOT_FOUND; 45459585STim.Szeto@Sun.COM goto done; 45469585STim.Szeto@Sun.COM } 45479585STim.Szeto@Sun.COM 45489585STim.Szeto@Sun.COM listCnt = stmfIoctl.stmf_obuf_nentries; 45499585STim.Szeto@Sun.COM 45509585STim.Szeto@Sun.COM /* 45519585STim.Szeto@Sun.COM * allocate caller's buffer with the final size 45529585STim.Szeto@Sun.COM */ 45539585STim.Szeto@Sun.COM *viewEntryList = (stmfViewEntryList *)calloc(1, 45549585STim.Szeto@Sun.COM sizeof (stmfViewEntryList) + listCnt * sizeof (stmfViewEntry)); 45559585STim.Szeto@Sun.COM if (*viewEntryList == NULL) { 45569585STim.Szeto@Sun.COM ret = STMF_ERROR_NOMEM; 45579585STim.Szeto@Sun.COM goto done; 45589585STim.Szeto@Sun.COM } 45599585STim.Szeto@Sun.COM 45609585STim.Szeto@Sun.COM (*viewEntryList)->cnt = listCnt; 45619585STim.Szeto@Sun.COM 45629585STim.Szeto@Sun.COM /* copy to caller's buffer */ 45639585STim.Szeto@Sun.COM for (i = 0; i < listCnt; i++) { 45649585STim.Szeto@Sun.COM (*viewEntryList)->ve[i].veIndexValid = B_TRUE; 45659585STim.Szeto@Sun.COM (*viewEntryList)->ve[i].veIndex = fVeList[i].ve_ndx; 45669585STim.Szeto@Sun.COM if (fVeList[i].ve_all_hosts == 1) { 45679585STim.Szeto@Sun.COM (*viewEntryList)->ve[i].allHosts = B_TRUE; 45689585STim.Szeto@Sun.COM } else { 45699585STim.Szeto@Sun.COM bcopy(fVeList[i].ve_host_group.name, 45709585STim.Szeto@Sun.COM (*viewEntryList)->ve[i].hostGroup, 45719585STim.Szeto@Sun.COM fVeList[i].ve_host_group.name_size); 45729585STim.Szeto@Sun.COM } 45739585STim.Szeto@Sun.COM if (fVeList[i].ve_all_targets == 1) { 45749585STim.Szeto@Sun.COM (*viewEntryList)->ve[i].allTargets = B_TRUE; 45759585STim.Szeto@Sun.COM } else { 45769585STim.Szeto@Sun.COM bcopy(fVeList[i].ve_target_group.name, 45779585STim.Szeto@Sun.COM (*viewEntryList)->ve[i].targetGroup, 45789585STim.Szeto@Sun.COM fVeList[i].ve_target_group.name_size); 45799585STim.Szeto@Sun.COM } 45809585STim.Szeto@Sun.COM bcopy(fVeList[i].ve_lu_nbr, (*viewEntryList)->ve[i].luNbr, 45819585STim.Szeto@Sun.COM sizeof ((*viewEntryList)->ve[i].luNbr)); 45829585STim.Szeto@Sun.COM (*viewEntryList)->ve[i].luNbrValid = B_TRUE; 45839585STim.Szeto@Sun.COM } 45849585STim.Szeto@Sun.COM 45859585STim.Szeto@Sun.COM /* 45869585STim.Szeto@Sun.COM * sort the list. This gives a consistent view across gets 45879585STim.Szeto@Sun.COM */ 45889585STim.Szeto@Sun.COM qsort((void *)&((*viewEntryList)->ve[0]), (*viewEntryList)->cnt, 45899585STim.Szeto@Sun.COM sizeof (stmfViewEntry), viewEntryCompare); 45909585STim.Szeto@Sun.COM 45919585STim.Szeto@Sun.COM done: 45929585STim.Szeto@Sun.COM (void) close(fd); 45939585STim.Szeto@Sun.COM /* 45949585STim.Szeto@Sun.COM * free internal buffers 45959585STim.Szeto@Sun.COM */ 45969585STim.Szeto@Sun.COM free(fVeList); 45977836SJohn.Forte@Sun.COM return (ret); 45987836SJohn.Forte@Sun.COM } 45997836SJohn.Forte@Sun.COM 46009585STim.Szeto@Sun.COM 46017836SJohn.Forte@Sun.COM /* 46027836SJohn.Forte@Sun.COM * loadHostGroups 46037836SJohn.Forte@Sun.COM * 46047836SJohn.Forte@Sun.COM * Purpose - issues the ioctl to load the host groups into stmf 46057836SJohn.Forte@Sun.COM * 46067836SJohn.Forte@Sun.COM * fd - file descriptor for the control node of stmf. 46077836SJohn.Forte@Sun.COM * groupList - populated host group list 46087836SJohn.Forte@Sun.COM */ 46097836SJohn.Forte@Sun.COM static int 46107836SJohn.Forte@Sun.COM loadHostGroups(int fd, stmfGroupList *groupList) 46117836SJohn.Forte@Sun.COM { 46127836SJohn.Forte@Sun.COM int i, j; 46137836SJohn.Forte@Sun.COM int ret = STMF_STATUS_SUCCESS; 46147836SJohn.Forte@Sun.COM stmfGroupProperties *groupProps = NULL; 46157836SJohn.Forte@Sun.COM 46167836SJohn.Forte@Sun.COM for (i = 0; i < groupList->cnt; i++) { 46177836SJohn.Forte@Sun.COM if ((ret = groupIoctl(fd, STMF_IOCTL_CREATE_HOST_GROUP, 46187836SJohn.Forte@Sun.COM &(groupList->name[i]))) != STMF_STATUS_SUCCESS) { 46197836SJohn.Forte@Sun.COM goto out; 46207836SJohn.Forte@Sun.COM } 46219585STim.Szeto@Sun.COM ret = iLoadGroupMembersFromPs(&(groupList->name[i]), 46229585STim.Szeto@Sun.COM &groupProps, HOST_GROUP); 46237836SJohn.Forte@Sun.COM for (j = 0; j < groupProps->cnt; j++) { 46247836SJohn.Forte@Sun.COM if ((ret = groupMemberIoctl(fd, STMF_IOCTL_ADD_HG_ENTRY, 46257836SJohn.Forte@Sun.COM &(groupList->name[i]), &(groupProps->name[j]))) 46267836SJohn.Forte@Sun.COM != STMF_STATUS_SUCCESS) { 46277836SJohn.Forte@Sun.COM goto out; 46287836SJohn.Forte@Sun.COM } 46297836SJohn.Forte@Sun.COM } 46307836SJohn.Forte@Sun.COM } 46317836SJohn.Forte@Sun.COM 46327836SJohn.Forte@Sun.COM 46337836SJohn.Forte@Sun.COM out: 46347836SJohn.Forte@Sun.COM stmfFreeMemory(groupProps); 46357836SJohn.Forte@Sun.COM return (ret); 46367836SJohn.Forte@Sun.COM } 46377836SJohn.Forte@Sun.COM 46387836SJohn.Forte@Sun.COM /* 46397836SJohn.Forte@Sun.COM * loadTargetGroups 46407836SJohn.Forte@Sun.COM * 46417836SJohn.Forte@Sun.COM * Purpose - issues the ioctl to load the target groups into stmf 46427836SJohn.Forte@Sun.COM * 46437836SJohn.Forte@Sun.COM * fd - file descriptor for the control node of stmf. 46447836SJohn.Forte@Sun.COM * groupList - populated target group list. 46457836SJohn.Forte@Sun.COM */ 46467836SJohn.Forte@Sun.COM static int 46477836SJohn.Forte@Sun.COM loadTargetGroups(int fd, stmfGroupList *groupList) 46487836SJohn.Forte@Sun.COM { 46497836SJohn.Forte@Sun.COM int i, j; 46507836SJohn.Forte@Sun.COM int ret = STMF_STATUS_SUCCESS; 46517836SJohn.Forte@Sun.COM stmfGroupProperties *groupProps = NULL; 46527836SJohn.Forte@Sun.COM 46537836SJohn.Forte@Sun.COM for (i = 0; i < groupList->cnt; i++) { 46547836SJohn.Forte@Sun.COM if ((ret = groupIoctl(fd, STMF_IOCTL_CREATE_TARGET_GROUP, 46557836SJohn.Forte@Sun.COM &(groupList->name[i]))) != STMF_STATUS_SUCCESS) { 46567836SJohn.Forte@Sun.COM goto out; 46577836SJohn.Forte@Sun.COM } 46589585STim.Szeto@Sun.COM ret = iLoadGroupMembersFromPs(&(groupList->name[i]), 46599585STim.Szeto@Sun.COM &groupProps, TARGET_GROUP); 46607836SJohn.Forte@Sun.COM for (j = 0; j < groupProps->cnt; j++) { 46617836SJohn.Forte@Sun.COM if ((ret = groupMemberIoctl(fd, STMF_IOCTL_ADD_TG_ENTRY, 46627836SJohn.Forte@Sun.COM &(groupList->name[i]), &(groupProps->name[j]))) 46637836SJohn.Forte@Sun.COM != STMF_STATUS_SUCCESS) { 46647836SJohn.Forte@Sun.COM goto out; 46657836SJohn.Forte@Sun.COM } 46667836SJohn.Forte@Sun.COM } 46677836SJohn.Forte@Sun.COM } 46687836SJohn.Forte@Sun.COM 46697836SJohn.Forte@Sun.COM 46707836SJohn.Forte@Sun.COM out: 46717836SJohn.Forte@Sun.COM stmfFreeMemory(groupProps); 46727836SJohn.Forte@Sun.COM return (ret); 46737836SJohn.Forte@Sun.COM } 46747836SJohn.Forte@Sun.COM 46757836SJohn.Forte@Sun.COM 46767836SJohn.Forte@Sun.COM /* 46777836SJohn.Forte@Sun.COM * loadStore 46787836SJohn.Forte@Sun.COM * 46797836SJohn.Forte@Sun.COM * Purpose: Load the configuration data from the store 46807836SJohn.Forte@Sun.COM * 46817836SJohn.Forte@Sun.COM * First load the host groups and target groups, then the view entries 46827836SJohn.Forte@Sun.COM * and finally the provider data 46837836SJohn.Forte@Sun.COM * 46847836SJohn.Forte@Sun.COM * fd - file descriptor of control node for stmf. 46857836SJohn.Forte@Sun.COM */ 46867836SJohn.Forte@Sun.COM static int 46877836SJohn.Forte@Sun.COM loadStore(int fd) 46887836SJohn.Forte@Sun.COM { 46897836SJohn.Forte@Sun.COM int ret; 46907836SJohn.Forte@Sun.COM int i, j; 46917836SJohn.Forte@Sun.COM stmfGroupList *groupList = NULL; 46927836SJohn.Forte@Sun.COM stmfGuidList *guidList = NULL; 46937836SJohn.Forte@Sun.COM stmfViewEntryList *viewEntryList = NULL; 46947836SJohn.Forte@Sun.COM stmfProviderList *providerList = NULL; 46957836SJohn.Forte@Sun.COM int providerType; 46967836SJohn.Forte@Sun.COM nvlist_t *nvl = NULL; 46977836SJohn.Forte@Sun.COM 46987836SJohn.Forte@Sun.COM 46997836SJohn.Forte@Sun.COM 47007836SJohn.Forte@Sun.COM /* load host groups */ 47019585STim.Szeto@Sun.COM ret = iLoadGroupFromPs(&groupList, HOST_GROUP); 47027836SJohn.Forte@Sun.COM if (ret != STMF_STATUS_SUCCESS) { 47037836SJohn.Forte@Sun.COM return (ret); 47047836SJohn.Forte@Sun.COM } 47057836SJohn.Forte@Sun.COM ret = loadHostGroups(fd, groupList); 47067836SJohn.Forte@Sun.COM if (ret != STMF_STATUS_SUCCESS) { 47077836SJohn.Forte@Sun.COM goto out; 47087836SJohn.Forte@Sun.COM } 47097836SJohn.Forte@Sun.COM 47107836SJohn.Forte@Sun.COM stmfFreeMemory(groupList); 47117836SJohn.Forte@Sun.COM groupList = NULL; 47127836SJohn.Forte@Sun.COM 47137836SJohn.Forte@Sun.COM /* load target groups */ 47149585STim.Szeto@Sun.COM ret = iLoadGroupFromPs(&groupList, TARGET_GROUP); 47157836SJohn.Forte@Sun.COM if (ret != STMF_STATUS_SUCCESS) { 47167836SJohn.Forte@Sun.COM goto out; 47177836SJohn.Forte@Sun.COM } 47187836SJohn.Forte@Sun.COM ret = loadTargetGroups(fd, groupList); 47197836SJohn.Forte@Sun.COM if (ret != STMF_STATUS_SUCCESS) { 47207836SJohn.Forte@Sun.COM goto out; 47217836SJohn.Forte@Sun.COM } 47227836SJohn.Forte@Sun.COM 47237836SJohn.Forte@Sun.COM stmfFreeMemory(groupList); 47247836SJohn.Forte@Sun.COM groupList = NULL; 47257836SJohn.Forte@Sun.COM 47267836SJohn.Forte@Sun.COM /* Get the guid list */ 47277836SJohn.Forte@Sun.COM ret = psGetLogicalUnitList(&guidList); 47287836SJohn.Forte@Sun.COM switch (ret) { 47297836SJohn.Forte@Sun.COM case STMF_PS_SUCCESS: 47307836SJohn.Forte@Sun.COM ret = STMF_STATUS_SUCCESS; 47317836SJohn.Forte@Sun.COM break; 47327836SJohn.Forte@Sun.COM case STMF_PS_ERROR_NOT_FOUND: 47337836SJohn.Forte@Sun.COM ret = STMF_ERROR_NOT_FOUND; 47347836SJohn.Forte@Sun.COM break; 47357836SJohn.Forte@Sun.COM case STMF_PS_ERROR_BUSY: 47367836SJohn.Forte@Sun.COM ret = STMF_ERROR_BUSY; 47377836SJohn.Forte@Sun.COM break; 47387836SJohn.Forte@Sun.COM case STMF_PS_ERROR_SERVICE_NOT_FOUND: 47397836SJohn.Forte@Sun.COM ret = STMF_ERROR_SERVICE_NOT_FOUND; 47407836SJohn.Forte@Sun.COM break; 47417836SJohn.Forte@Sun.COM case STMF_PS_ERROR_VERSION_MISMATCH: 47427836SJohn.Forte@Sun.COM ret = STMF_ERROR_SERVICE_DATA_VERSION; 47437836SJohn.Forte@Sun.COM break; 47447836SJohn.Forte@Sun.COM default: 47457836SJohn.Forte@Sun.COM ret = STMF_STATUS_ERROR; 47467836SJohn.Forte@Sun.COM break; 47477836SJohn.Forte@Sun.COM } 47487836SJohn.Forte@Sun.COM 47497836SJohn.Forte@Sun.COM if (ret != STMF_STATUS_SUCCESS) { 47507836SJohn.Forte@Sun.COM goto out; 47517836SJohn.Forte@Sun.COM } 47527836SJohn.Forte@Sun.COM 47537836SJohn.Forte@Sun.COM /* 47547836SJohn.Forte@Sun.COM * We have the guid list, now get the corresponding 47557836SJohn.Forte@Sun.COM * view entries for each guid 47567836SJohn.Forte@Sun.COM */ 47577836SJohn.Forte@Sun.COM for (i = 0; i < guidList->cnt; i++) { 47587836SJohn.Forte@Sun.COM ret = psGetViewEntryList(&guidList->guid[i], &viewEntryList); 47597836SJohn.Forte@Sun.COM switch (ret) { 47607836SJohn.Forte@Sun.COM case STMF_PS_SUCCESS: 47617836SJohn.Forte@Sun.COM ret = STMF_STATUS_SUCCESS; 47627836SJohn.Forte@Sun.COM break; 47637836SJohn.Forte@Sun.COM case STMF_PS_ERROR_NOT_FOUND: 47647836SJohn.Forte@Sun.COM ret = STMF_ERROR_NOT_FOUND; 47657836SJohn.Forte@Sun.COM break; 47667836SJohn.Forte@Sun.COM case STMF_PS_ERROR_BUSY: 47677836SJohn.Forte@Sun.COM ret = STMF_ERROR_BUSY; 47687836SJohn.Forte@Sun.COM break; 47697836SJohn.Forte@Sun.COM case STMF_PS_ERROR_SERVICE_NOT_FOUND: 47707836SJohn.Forte@Sun.COM ret = STMF_ERROR_SERVICE_NOT_FOUND; 47717836SJohn.Forte@Sun.COM break; 47727836SJohn.Forte@Sun.COM case STMF_PS_ERROR_VERSION_MISMATCH: 47737836SJohn.Forte@Sun.COM ret = STMF_ERROR_SERVICE_DATA_VERSION; 47747836SJohn.Forte@Sun.COM break; 47757836SJohn.Forte@Sun.COM default: 47767836SJohn.Forte@Sun.COM ret = STMF_STATUS_ERROR; 47777836SJohn.Forte@Sun.COM break; 47787836SJohn.Forte@Sun.COM } 47797836SJohn.Forte@Sun.COM if (ret != STMF_STATUS_SUCCESS) { 47807836SJohn.Forte@Sun.COM goto out; 47817836SJohn.Forte@Sun.COM } 47827836SJohn.Forte@Sun.COM for (j = 0; j < viewEntryList->cnt; j++) { 47837836SJohn.Forte@Sun.COM ret = addViewEntryIoctl(fd, &guidList->guid[i], 47847836SJohn.Forte@Sun.COM &viewEntryList->ve[j]); 47857836SJohn.Forte@Sun.COM if (ret != STMF_STATUS_SUCCESS) { 47867836SJohn.Forte@Sun.COM goto out; 47877836SJohn.Forte@Sun.COM } 47887836SJohn.Forte@Sun.COM } 47897836SJohn.Forte@Sun.COM } 47907836SJohn.Forte@Sun.COM 47917836SJohn.Forte@Sun.COM /* get the list of providers that have data */ 47927836SJohn.Forte@Sun.COM ret = psGetProviderDataList(&providerList); 47937836SJohn.Forte@Sun.COM switch (ret) { 47947836SJohn.Forte@Sun.COM case STMF_PS_SUCCESS: 47957836SJohn.Forte@Sun.COM ret = STMF_STATUS_SUCCESS; 47967836SJohn.Forte@Sun.COM break; 47977836SJohn.Forte@Sun.COM case STMF_PS_ERROR_NOT_FOUND: 47987836SJohn.Forte@Sun.COM ret = STMF_ERROR_NOT_FOUND; 47997836SJohn.Forte@Sun.COM break; 48007836SJohn.Forte@Sun.COM case STMF_PS_ERROR_BUSY: 48017836SJohn.Forte@Sun.COM ret = STMF_ERROR_BUSY; 48027836SJohn.Forte@Sun.COM break; 48037836SJohn.Forte@Sun.COM case STMF_PS_ERROR_SERVICE_NOT_FOUND: 48047836SJohn.Forte@Sun.COM ret = STMF_ERROR_SERVICE_NOT_FOUND; 48057836SJohn.Forte@Sun.COM break; 48067836SJohn.Forte@Sun.COM case STMF_PS_ERROR_VERSION_MISMATCH: 48077836SJohn.Forte@Sun.COM ret = STMF_ERROR_SERVICE_DATA_VERSION; 48087836SJohn.Forte@Sun.COM break; 48097836SJohn.Forte@Sun.COM default: 48107836SJohn.Forte@Sun.COM ret = STMF_STATUS_ERROR; 48117836SJohn.Forte@Sun.COM break; 48127836SJohn.Forte@Sun.COM } 48137836SJohn.Forte@Sun.COM if (ret != STMF_STATUS_SUCCESS) { 48147836SJohn.Forte@Sun.COM goto out; 48157836SJohn.Forte@Sun.COM } 48167836SJohn.Forte@Sun.COM 48177836SJohn.Forte@Sun.COM for (i = 0; i < providerList->cnt; i++) { 48187836SJohn.Forte@Sun.COM providerType = providerList->provider[i].providerType; 48197836SJohn.Forte@Sun.COM ret = psGetProviderData(providerList->provider[i].name, 48207836SJohn.Forte@Sun.COM &nvl, providerType, NULL); 48217836SJohn.Forte@Sun.COM switch (ret) { 48227836SJohn.Forte@Sun.COM case STMF_PS_SUCCESS: 48237836SJohn.Forte@Sun.COM ret = STMF_STATUS_SUCCESS; 48247836SJohn.Forte@Sun.COM break; 48257836SJohn.Forte@Sun.COM case STMF_PS_ERROR_NOT_FOUND: 48267836SJohn.Forte@Sun.COM ret = STMF_ERROR_NOT_FOUND; 48277836SJohn.Forte@Sun.COM break; 48287836SJohn.Forte@Sun.COM case STMF_PS_ERROR_BUSY: 48297836SJohn.Forte@Sun.COM ret = STMF_ERROR_BUSY; 48307836SJohn.Forte@Sun.COM break; 48317836SJohn.Forte@Sun.COM case STMF_PS_ERROR_SERVICE_NOT_FOUND: 48327836SJohn.Forte@Sun.COM ret = STMF_ERROR_SERVICE_NOT_FOUND; 48337836SJohn.Forte@Sun.COM break; 48347836SJohn.Forte@Sun.COM case STMF_PS_ERROR_VERSION_MISMATCH: 48357836SJohn.Forte@Sun.COM ret = STMF_ERROR_SERVICE_DATA_VERSION; 48367836SJohn.Forte@Sun.COM break; 48377836SJohn.Forte@Sun.COM default: 48387836SJohn.Forte@Sun.COM ret = STMF_STATUS_ERROR; 48397836SJohn.Forte@Sun.COM break; 48407836SJohn.Forte@Sun.COM } 48417836SJohn.Forte@Sun.COM if (ret != STMF_STATUS_SUCCESS) { 48427836SJohn.Forte@Sun.COM goto out; 48437836SJohn.Forte@Sun.COM } 48447836SJohn.Forte@Sun.COM 48457836SJohn.Forte@Sun.COM /* call setProviderData */ 48467836SJohn.Forte@Sun.COM ret = setProviderData(fd, providerList->provider[i].name, nvl, 48479585STim.Szeto@Sun.COM providerType, NULL); 48487836SJohn.Forte@Sun.COM switch (ret) { 48497836SJohn.Forte@Sun.COM case STMF_PS_SUCCESS: 48507836SJohn.Forte@Sun.COM ret = STMF_STATUS_SUCCESS; 48517836SJohn.Forte@Sun.COM break; 48527836SJohn.Forte@Sun.COM case STMF_PS_ERROR_NOT_FOUND: 48537836SJohn.Forte@Sun.COM ret = STMF_ERROR_NOT_FOUND; 48547836SJohn.Forte@Sun.COM break; 48557836SJohn.Forte@Sun.COM case STMF_PS_ERROR_BUSY: 48567836SJohn.Forte@Sun.COM ret = STMF_ERROR_BUSY; 48577836SJohn.Forte@Sun.COM break; 48587836SJohn.Forte@Sun.COM case STMF_PS_ERROR_SERVICE_NOT_FOUND: 48597836SJohn.Forte@Sun.COM ret = STMF_ERROR_SERVICE_NOT_FOUND; 48607836SJohn.Forte@Sun.COM break; 48617836SJohn.Forte@Sun.COM case STMF_PS_ERROR_VERSION_MISMATCH: 48627836SJohn.Forte@Sun.COM ret = STMF_ERROR_SERVICE_DATA_VERSION; 48637836SJohn.Forte@Sun.COM break; 48647836SJohn.Forte@Sun.COM default: 48657836SJohn.Forte@Sun.COM ret = STMF_STATUS_ERROR; 48667836SJohn.Forte@Sun.COM break; 48677836SJohn.Forte@Sun.COM } 48687836SJohn.Forte@Sun.COM if (ret != STMF_STATUS_SUCCESS) { 48697836SJohn.Forte@Sun.COM goto out; 48707836SJohn.Forte@Sun.COM } 48717836SJohn.Forte@Sun.COM 48727836SJohn.Forte@Sun.COM nvlist_free(nvl); 48737836SJohn.Forte@Sun.COM nvl = NULL; 48747836SJohn.Forte@Sun.COM } 48757836SJohn.Forte@Sun.COM out: 48767836SJohn.Forte@Sun.COM if (groupList != NULL) { 48777836SJohn.Forte@Sun.COM free(groupList); 48787836SJohn.Forte@Sun.COM } 48797836SJohn.Forte@Sun.COM if (guidList != NULL) { 48807836SJohn.Forte@Sun.COM free(guidList); 48817836SJohn.Forte@Sun.COM } 48827836SJohn.Forte@Sun.COM if (viewEntryList != NULL) { 48837836SJohn.Forte@Sun.COM free(viewEntryList); 48847836SJohn.Forte@Sun.COM } 48857836SJohn.Forte@Sun.COM if (nvl != NULL) { 48867836SJohn.Forte@Sun.COM nvlist_free(nvl); 48877836SJohn.Forte@Sun.COM } 48887836SJohn.Forte@Sun.COM return (ret); 48897836SJohn.Forte@Sun.COM } 48907836SJohn.Forte@Sun.COM 48917836SJohn.Forte@Sun.COM /* 4892*10725SJohn.Forte@Sun.COM * stmfGetAluaState 4893*10725SJohn.Forte@Sun.COM * 4894*10725SJohn.Forte@Sun.COM * Purpose - Get the alua state 4895*10725SJohn.Forte@Sun.COM * 4896*10725SJohn.Forte@Sun.COM */ 4897*10725SJohn.Forte@Sun.COM int 4898*10725SJohn.Forte@Sun.COM stmfGetAluaState(boolean_t *enabled, uint32_t *node) 4899*10725SJohn.Forte@Sun.COM { 4900*10725SJohn.Forte@Sun.COM int ret = STMF_STATUS_SUCCESS; 4901*10725SJohn.Forte@Sun.COM int fd; 4902*10725SJohn.Forte@Sun.COM stmf_iocdata_t stmfIoctl = {0}; 4903*10725SJohn.Forte@Sun.COM stmf_alua_state_desc_t alua_state = {0}; 4904*10725SJohn.Forte@Sun.COM int ioctlRet; 4905*10725SJohn.Forte@Sun.COM 4906*10725SJohn.Forte@Sun.COM if (enabled == NULL || node == NULL) { 4907*10725SJohn.Forte@Sun.COM return (STMF_ERROR_INVALID_ARG); 4908*10725SJohn.Forte@Sun.COM } 4909*10725SJohn.Forte@Sun.COM 4910*10725SJohn.Forte@Sun.COM /* 4911*10725SJohn.Forte@Sun.COM * Open control node for stmf 4912*10725SJohn.Forte@Sun.COM */ 4913*10725SJohn.Forte@Sun.COM if ((ret = openStmf(OPEN_STMF, &fd)) != STMF_STATUS_SUCCESS) 4914*10725SJohn.Forte@Sun.COM return (ret); 4915*10725SJohn.Forte@Sun.COM 4916*10725SJohn.Forte@Sun.COM /* 4917*10725SJohn.Forte@Sun.COM * Issue ioctl to get the stmf state 4918*10725SJohn.Forte@Sun.COM */ 4919*10725SJohn.Forte@Sun.COM stmfIoctl.stmf_version = STMF_VERSION_1; 4920*10725SJohn.Forte@Sun.COM stmfIoctl.stmf_obuf_size = sizeof (alua_state); 4921*10725SJohn.Forte@Sun.COM stmfIoctl.stmf_obuf = (uint64_t)(unsigned long)&alua_state; 4922*10725SJohn.Forte@Sun.COM ioctlRet = ioctl(fd, STMF_IOCTL_GET_ALUA_STATE, &stmfIoctl); 4923*10725SJohn.Forte@Sun.COM 4924*10725SJohn.Forte@Sun.COM (void) close(fd); 4925*10725SJohn.Forte@Sun.COM 4926*10725SJohn.Forte@Sun.COM if (ioctlRet != 0) { 4927*10725SJohn.Forte@Sun.COM switch (errno) { 4928*10725SJohn.Forte@Sun.COM case EBUSY: 4929*10725SJohn.Forte@Sun.COM ret = STMF_ERROR_BUSY; 4930*10725SJohn.Forte@Sun.COM break; 4931*10725SJohn.Forte@Sun.COM case EPERM: 4932*10725SJohn.Forte@Sun.COM case EACCES: 4933*10725SJohn.Forte@Sun.COM ret = STMF_ERROR_PERM; 4934*10725SJohn.Forte@Sun.COM break; 4935*10725SJohn.Forte@Sun.COM default: 4936*10725SJohn.Forte@Sun.COM syslog(LOG_DEBUG, 4937*10725SJohn.Forte@Sun.COM "getStmfState:ioctl errno(%d)", errno); 4938*10725SJohn.Forte@Sun.COM ret = STMF_STATUS_ERROR; 4939*10725SJohn.Forte@Sun.COM break; 4940*10725SJohn.Forte@Sun.COM } 4941*10725SJohn.Forte@Sun.COM } else { 4942*10725SJohn.Forte@Sun.COM if (alua_state.alua_state == 1) { 4943*10725SJohn.Forte@Sun.COM *enabled = B_TRUE; 4944*10725SJohn.Forte@Sun.COM } else { 4945*10725SJohn.Forte@Sun.COM *enabled = B_FALSE; 4946*10725SJohn.Forte@Sun.COM } 4947*10725SJohn.Forte@Sun.COM *node = alua_state.alua_node; 4948*10725SJohn.Forte@Sun.COM } 4949*10725SJohn.Forte@Sun.COM 4950*10725SJohn.Forte@Sun.COM return (ret); 4951*10725SJohn.Forte@Sun.COM } 4952*10725SJohn.Forte@Sun.COM 4953*10725SJohn.Forte@Sun.COM /* 4954*10725SJohn.Forte@Sun.COM * stmfSetAluaState 4955*10725SJohn.Forte@Sun.COM * 4956*10725SJohn.Forte@Sun.COM * Purpose - set the alua state to enabled/disabled 4957*10725SJohn.Forte@Sun.COM * 4958*10725SJohn.Forte@Sun.COM */ 4959*10725SJohn.Forte@Sun.COM int 4960*10725SJohn.Forte@Sun.COM stmfSetAluaState(boolean_t enabled, uint32_t node) 4961*10725SJohn.Forte@Sun.COM { 4962*10725SJohn.Forte@Sun.COM int ret = STMF_STATUS_SUCCESS; 4963*10725SJohn.Forte@Sun.COM int fd; 4964*10725SJohn.Forte@Sun.COM stmf_iocdata_t stmfIoctl = {0}; 4965*10725SJohn.Forte@Sun.COM stmf_alua_state_desc_t alua_state = {0}; 4966*10725SJohn.Forte@Sun.COM int ioctlRet; 4967*10725SJohn.Forte@Sun.COM 4968*10725SJohn.Forte@Sun.COM if ((enabled != B_TRUE && enabled != B_FALSE) || (node > 1)) { 4969*10725SJohn.Forte@Sun.COM return (STMF_ERROR_INVALID_ARG); 4970*10725SJohn.Forte@Sun.COM } 4971*10725SJohn.Forte@Sun.COM 4972*10725SJohn.Forte@Sun.COM if (enabled) { 4973*10725SJohn.Forte@Sun.COM alua_state.alua_state = 1; 4974*10725SJohn.Forte@Sun.COM } 4975*10725SJohn.Forte@Sun.COM 4976*10725SJohn.Forte@Sun.COM alua_state.alua_node = node; 4977*10725SJohn.Forte@Sun.COM 4978*10725SJohn.Forte@Sun.COM /* 4979*10725SJohn.Forte@Sun.COM * Open control node for stmf 4980*10725SJohn.Forte@Sun.COM */ 4981*10725SJohn.Forte@Sun.COM if ((ret = openStmf(OPEN_STMF, &fd)) != STMF_STATUS_SUCCESS) 4982*10725SJohn.Forte@Sun.COM return (ret); 4983*10725SJohn.Forte@Sun.COM 4984*10725SJohn.Forte@Sun.COM /* 4985*10725SJohn.Forte@Sun.COM * Issue ioctl to get the stmf state 4986*10725SJohn.Forte@Sun.COM */ 4987*10725SJohn.Forte@Sun.COM stmfIoctl.stmf_version = STMF_VERSION_1; 4988*10725SJohn.Forte@Sun.COM stmfIoctl.stmf_ibuf_size = sizeof (alua_state); 4989*10725SJohn.Forte@Sun.COM stmfIoctl.stmf_ibuf = (uint64_t)(unsigned long)&alua_state; 4990*10725SJohn.Forte@Sun.COM ioctlRet = ioctl(fd, STMF_IOCTL_SET_ALUA_STATE, &stmfIoctl); 4991*10725SJohn.Forte@Sun.COM 4992*10725SJohn.Forte@Sun.COM (void) close(fd); 4993*10725SJohn.Forte@Sun.COM 4994*10725SJohn.Forte@Sun.COM if (ioctlRet != 0) { 4995*10725SJohn.Forte@Sun.COM switch (errno) { 4996*10725SJohn.Forte@Sun.COM case EBUSY: 4997*10725SJohn.Forte@Sun.COM ret = STMF_ERROR_BUSY; 4998*10725SJohn.Forte@Sun.COM break; 4999*10725SJohn.Forte@Sun.COM case EPERM: 5000*10725SJohn.Forte@Sun.COM case EACCES: 5001*10725SJohn.Forte@Sun.COM ret = STMF_ERROR_PERM; 5002*10725SJohn.Forte@Sun.COM break; 5003*10725SJohn.Forte@Sun.COM default: 5004*10725SJohn.Forte@Sun.COM syslog(LOG_DEBUG, 5005*10725SJohn.Forte@Sun.COM "getStmfState:ioctl errno(%d)", errno); 5006*10725SJohn.Forte@Sun.COM ret = STMF_STATUS_ERROR; 5007*10725SJohn.Forte@Sun.COM break; 5008*10725SJohn.Forte@Sun.COM } 5009*10725SJohn.Forte@Sun.COM } 5010*10725SJohn.Forte@Sun.COM if (ret == STMF_STATUS_SUCCESS) { 5011*10725SJohn.Forte@Sun.COM deleteNonActiveLus(); 5012*10725SJohn.Forte@Sun.COM } 5013*10725SJohn.Forte@Sun.COM 5014*10725SJohn.Forte@Sun.COM return (ret); 5015*10725SJohn.Forte@Sun.COM } 5016*10725SJohn.Forte@Sun.COM 5017*10725SJohn.Forte@Sun.COM static void 5018*10725SJohn.Forte@Sun.COM deleteNonActiveLus() 5019*10725SJohn.Forte@Sun.COM { 5020*10725SJohn.Forte@Sun.COM int stmfRet; 5021*10725SJohn.Forte@Sun.COM int i; 5022*10725SJohn.Forte@Sun.COM stmfGuidList *luList; 5023*10725SJohn.Forte@Sun.COM luResource hdl = NULL; 5024*10725SJohn.Forte@Sun.COM char propVal[10]; 5025*10725SJohn.Forte@Sun.COM size_t propValSize = sizeof (propVal); 5026*10725SJohn.Forte@Sun.COM 5027*10725SJohn.Forte@Sun.COM stmfRet = stmfGetLogicalUnitList(&luList); 5028*10725SJohn.Forte@Sun.COM if (stmfRet != STMF_STATUS_SUCCESS) { 5029*10725SJohn.Forte@Sun.COM return; 5030*10725SJohn.Forte@Sun.COM } 5031*10725SJohn.Forte@Sun.COM 5032*10725SJohn.Forte@Sun.COM for (i = 0; i < luList->cnt; i++) { 5033*10725SJohn.Forte@Sun.COM stmfRet = stmfGetLuResource(&luList->guid[i], &hdl); 5034*10725SJohn.Forte@Sun.COM if (stmfRet != STMF_STATUS_SUCCESS) { 5035*10725SJohn.Forte@Sun.COM goto err; 5036*10725SJohn.Forte@Sun.COM } 5037*10725SJohn.Forte@Sun.COM stmfRet = stmfGetLuProp(hdl, STMF_LU_PROP_ACCESS_STATE, propVal, 5038*10725SJohn.Forte@Sun.COM &propValSize); 5039*10725SJohn.Forte@Sun.COM if (stmfRet != STMF_STATUS_SUCCESS) { 5040*10725SJohn.Forte@Sun.COM goto err; 5041*10725SJohn.Forte@Sun.COM } 5042*10725SJohn.Forte@Sun.COM if (propVal[0] == '0') { 5043*10725SJohn.Forte@Sun.COM (void) stmfFreeLuResource(hdl); 5044*10725SJohn.Forte@Sun.COM hdl = NULL; 5045*10725SJohn.Forte@Sun.COM continue; 5046*10725SJohn.Forte@Sun.COM } 5047*10725SJohn.Forte@Sun.COM (void) stmfDeleteLu(&luList->guid[i]); 5048*10725SJohn.Forte@Sun.COM (void) stmfFreeLuResource(hdl); 5049*10725SJohn.Forte@Sun.COM hdl = NULL; 5050*10725SJohn.Forte@Sun.COM } 5051*10725SJohn.Forte@Sun.COM 5052*10725SJohn.Forte@Sun.COM err: 5053*10725SJohn.Forte@Sun.COM stmfFreeMemory(luList); 5054*10725SJohn.Forte@Sun.COM (void) stmfFreeLuResource(hdl); 5055*10725SJohn.Forte@Sun.COM } 5056*10725SJohn.Forte@Sun.COM 5057*10725SJohn.Forte@Sun.COM /* 50587836SJohn.Forte@Sun.COM * stmfLoadConfig 50597836SJohn.Forte@Sun.COM * 50607836SJohn.Forte@Sun.COM * Purpose - load the configuration data from smf into stmf 50617836SJohn.Forte@Sun.COM * 50627836SJohn.Forte@Sun.COM */ 50637836SJohn.Forte@Sun.COM int 50647836SJohn.Forte@Sun.COM stmfLoadConfig(void) 50657836SJohn.Forte@Sun.COM { 50669585STim.Szeto@Sun.COM int ret = STMF_STATUS_SUCCESS; 50677836SJohn.Forte@Sun.COM int fd; 50687836SJohn.Forte@Sun.COM stmf_state_desc_t stmfStateSet; 50697836SJohn.Forte@Sun.COM stmfState state; 50707836SJohn.Forte@Sun.COM 50719585STim.Szeto@Sun.COM if (iGetPersistMethod() == STMF_PERSIST_NONE) { 50729585STim.Szeto@Sun.COM stmfStateSet.state = STMF_STATE_OFFLINE; 507310560SSusan.Gleeson@Sun.COM 50749585STim.Szeto@Sun.COM if ((ret = openStmf(OPEN_EXCL_STMF, &fd)) 50759585STim.Szeto@Sun.COM != STMF_STATUS_SUCCESS) { 50769585STim.Szeto@Sun.COM return (ret); 50779585STim.Szeto@Sun.COM } 507810560SSusan.Gleeson@Sun.COM /* 507910560SSusan.Gleeson@Sun.COM * Configuration not stored persistently; nothing to 508010560SSusan.Gleeson@Sun.COM * initialize so do not set to STMF_CONFIG_INIT. 508110560SSusan.Gleeson@Sun.COM */ 50829585STim.Szeto@Sun.COM stmfStateSet.config_state = STMF_CONFIG_INIT_DONE; 50839585STim.Szeto@Sun.COM goto done; 50849585STim.Szeto@Sun.COM } 50857836SJohn.Forte@Sun.COM 50867836SJohn.Forte@Sun.COM /* Check to ensure service exists */ 50877836SJohn.Forte@Sun.COM if (psCheckService() != STMF_STATUS_SUCCESS) { 50887836SJohn.Forte@Sun.COM return (STMF_ERROR_SERVICE_NOT_FOUND); 50897836SJohn.Forte@Sun.COM } 50907836SJohn.Forte@Sun.COM 50917836SJohn.Forte@Sun.COM ret = stmfGetState(&state); 50927836SJohn.Forte@Sun.COM if (ret == STMF_STATUS_SUCCESS) { 50937836SJohn.Forte@Sun.COM if (state.operationalState != STMF_SERVICE_STATE_OFFLINE) { 50947836SJohn.Forte@Sun.COM return (STMF_ERROR_SERVICE_ONLINE); 50957836SJohn.Forte@Sun.COM } 50967836SJohn.Forte@Sun.COM } else { 50977836SJohn.Forte@Sun.COM return (STMF_STATUS_ERROR); 50987836SJohn.Forte@Sun.COM } 50997836SJohn.Forte@Sun.COM 51007836SJohn.Forte@Sun.COM 51017836SJohn.Forte@Sun.COM stmfStateSet.state = STMF_STATE_OFFLINE; 51027836SJohn.Forte@Sun.COM stmfStateSet.config_state = STMF_CONFIG_INIT; 51037836SJohn.Forte@Sun.COM 51047836SJohn.Forte@Sun.COM /* 51057836SJohn.Forte@Sun.COM * Open control node for stmf 51067836SJohn.Forte@Sun.COM */ 51077836SJohn.Forte@Sun.COM if ((ret = openStmf(OPEN_EXCL_STMF, &fd)) != STMF_STATUS_SUCCESS) 51087836SJohn.Forte@Sun.COM return (ret); 51097836SJohn.Forte@Sun.COM 51107836SJohn.Forte@Sun.COM ret = setStmfState(fd, &stmfStateSet, STMF_SERVICE_TYPE); 51117836SJohn.Forte@Sun.COM if (ret != STMF_STATUS_SUCCESS) { 51127836SJohn.Forte@Sun.COM goto done; 51137836SJohn.Forte@Sun.COM } 51147836SJohn.Forte@Sun.COM 51157836SJohn.Forte@Sun.COM /* Load the persistent configuration data */ 51167836SJohn.Forte@Sun.COM ret = loadStore(fd); 51177836SJohn.Forte@Sun.COM if (ret != 0) { 51187836SJohn.Forte@Sun.COM goto done; 51197836SJohn.Forte@Sun.COM } 51207836SJohn.Forte@Sun.COM 51217836SJohn.Forte@Sun.COM stmfStateSet.state = STMF_STATE_OFFLINE; 51227836SJohn.Forte@Sun.COM stmfStateSet.config_state = STMF_CONFIG_INIT_DONE; 51237836SJohn.Forte@Sun.COM 51247836SJohn.Forte@Sun.COM done: 51257836SJohn.Forte@Sun.COM if (ret == STMF_STATUS_SUCCESS) { 51267836SJohn.Forte@Sun.COM ret = setStmfState(fd, &stmfStateSet, STMF_SERVICE_TYPE); 51277836SJohn.Forte@Sun.COM } 51287836SJohn.Forte@Sun.COM (void) close(fd); 51297836SJohn.Forte@Sun.COM return (ret); 51307836SJohn.Forte@Sun.COM } 51317836SJohn.Forte@Sun.COM 51329585STim.Szeto@Sun.COM 51337836SJohn.Forte@Sun.COM /* 51347836SJohn.Forte@Sun.COM * getStmfState 51357836SJohn.Forte@Sun.COM * 51367836SJohn.Forte@Sun.COM * stmfState - pointer to stmf_state_desc_t structure. Will contain the state 51377836SJohn.Forte@Sun.COM * information of the stmf service on success. 51387836SJohn.Forte@Sun.COM */ 51397836SJohn.Forte@Sun.COM static int 51407836SJohn.Forte@Sun.COM getStmfState(stmf_state_desc_t *stmfState) 51417836SJohn.Forte@Sun.COM { 51427836SJohn.Forte@Sun.COM int ret = STMF_STATUS_SUCCESS; 51437836SJohn.Forte@Sun.COM int fd; 51447836SJohn.Forte@Sun.COM int ioctlRet; 51457836SJohn.Forte@Sun.COM stmf_iocdata_t stmfIoctl; 51467836SJohn.Forte@Sun.COM 51477836SJohn.Forte@Sun.COM /* 51487836SJohn.Forte@Sun.COM * Open control node for stmf 51497836SJohn.Forte@Sun.COM */ 51507836SJohn.Forte@Sun.COM if ((ret = openStmf(OPEN_STMF, &fd)) != STMF_STATUS_SUCCESS) 51517836SJohn.Forte@Sun.COM return (ret); 51527836SJohn.Forte@Sun.COM 51537836SJohn.Forte@Sun.COM bzero(&stmfIoctl, sizeof (stmfIoctl)); 51547836SJohn.Forte@Sun.COM /* 51557836SJohn.Forte@Sun.COM * Issue ioctl to get the stmf state 51567836SJohn.Forte@Sun.COM */ 51577836SJohn.Forte@Sun.COM stmfIoctl.stmf_version = STMF_VERSION_1; 51587836SJohn.Forte@Sun.COM stmfIoctl.stmf_ibuf_size = sizeof (stmf_state_desc_t); 51597836SJohn.Forte@Sun.COM stmfIoctl.stmf_ibuf = (uint64_t)(unsigned long)stmfState; 51607836SJohn.Forte@Sun.COM stmfIoctl.stmf_obuf_size = sizeof (stmf_state_desc_t); 51617836SJohn.Forte@Sun.COM stmfIoctl.stmf_obuf = (uint64_t)(unsigned long)stmfState; 51627836SJohn.Forte@Sun.COM ioctlRet = ioctl(fd, STMF_IOCTL_GET_STMF_STATE, &stmfIoctl); 51637836SJohn.Forte@Sun.COM 51647836SJohn.Forte@Sun.COM (void) close(fd); 51657836SJohn.Forte@Sun.COM 51667836SJohn.Forte@Sun.COM if (ioctlRet != 0) { 51677836SJohn.Forte@Sun.COM switch (errno) { 51687836SJohn.Forte@Sun.COM case EBUSY: 51697836SJohn.Forte@Sun.COM ret = STMF_ERROR_BUSY; 51707836SJohn.Forte@Sun.COM break; 51717836SJohn.Forte@Sun.COM case EPERM: 51727836SJohn.Forte@Sun.COM case EACCES: 51737836SJohn.Forte@Sun.COM ret = STMF_ERROR_PERM; 51747836SJohn.Forte@Sun.COM break; 51757836SJohn.Forte@Sun.COM default: 51767836SJohn.Forte@Sun.COM syslog(LOG_DEBUG, 51777836SJohn.Forte@Sun.COM "getStmfState:ioctl errno(%d)", errno); 51787836SJohn.Forte@Sun.COM ret = STMF_STATUS_ERROR; 51797836SJohn.Forte@Sun.COM break; 51807836SJohn.Forte@Sun.COM } 51817836SJohn.Forte@Sun.COM } 51827836SJohn.Forte@Sun.COM return (ret); 51837836SJohn.Forte@Sun.COM } 51847836SJohn.Forte@Sun.COM 51857836SJohn.Forte@Sun.COM 51867836SJohn.Forte@Sun.COM /* 51877836SJohn.Forte@Sun.COM * setStmfState 51887836SJohn.Forte@Sun.COM * 51897836SJohn.Forte@Sun.COM * stmfState - pointer to caller set state structure 51907836SJohn.Forte@Sun.COM * objectType - one of: 51917836SJohn.Forte@Sun.COM * LOGICAL_UNIT_TYPE 51927836SJohn.Forte@Sun.COM * TARGET_TYPE 51937836SJohn.Forte@Sun.COM * STMF_SERVICE_TYPE 51947836SJohn.Forte@Sun.COM */ 51957836SJohn.Forte@Sun.COM static int 51967836SJohn.Forte@Sun.COM setStmfState(int fd, stmf_state_desc_t *stmfState, int objectType) 51977836SJohn.Forte@Sun.COM { 51987836SJohn.Forte@Sun.COM int ret = STMF_STATUS_SUCCESS; 51997836SJohn.Forte@Sun.COM int ioctlRet; 52007836SJohn.Forte@Sun.COM int cmd; 52017836SJohn.Forte@Sun.COM stmf_iocdata_t stmfIoctl; 52027836SJohn.Forte@Sun.COM 52037836SJohn.Forte@Sun.COM switch (objectType) { 52047836SJohn.Forte@Sun.COM case LOGICAL_UNIT_TYPE: 52057836SJohn.Forte@Sun.COM cmd = STMF_IOCTL_SET_LU_STATE; 52067836SJohn.Forte@Sun.COM break; 52077836SJohn.Forte@Sun.COM case TARGET_TYPE: 52087836SJohn.Forte@Sun.COM cmd = STMF_IOCTL_SET_TARGET_PORT_STATE; 52097836SJohn.Forte@Sun.COM break; 52107836SJohn.Forte@Sun.COM case STMF_SERVICE_TYPE: 52117836SJohn.Forte@Sun.COM cmd = STMF_IOCTL_SET_STMF_STATE; 52127836SJohn.Forte@Sun.COM break; 52137836SJohn.Forte@Sun.COM default: 52147836SJohn.Forte@Sun.COM ret = STMF_STATUS_ERROR; 52157836SJohn.Forte@Sun.COM goto done; 52167836SJohn.Forte@Sun.COM } 52177836SJohn.Forte@Sun.COM 52187836SJohn.Forte@Sun.COM bzero(&stmfIoctl, sizeof (stmfIoctl)); 52197836SJohn.Forte@Sun.COM /* 52207836SJohn.Forte@Sun.COM * Issue ioctl to set the stmf state 52217836SJohn.Forte@Sun.COM */ 52227836SJohn.Forte@Sun.COM stmfIoctl.stmf_version = STMF_VERSION_1; 52237836SJohn.Forte@Sun.COM stmfIoctl.stmf_ibuf_size = sizeof (stmf_state_desc_t); 52247836SJohn.Forte@Sun.COM stmfIoctl.stmf_ibuf = (uint64_t)(unsigned long)stmfState; 52257836SJohn.Forte@Sun.COM ioctlRet = ioctl(fd, cmd, &stmfIoctl); 52267836SJohn.Forte@Sun.COM if (ioctlRet != 0) { 52277836SJohn.Forte@Sun.COM switch (errno) { 52287836SJohn.Forte@Sun.COM case EBUSY: 52297836SJohn.Forte@Sun.COM ret = STMF_ERROR_BUSY; 52307836SJohn.Forte@Sun.COM break; 52319585STim.Szeto@Sun.COM case EPERM: 52327836SJohn.Forte@Sun.COM case EACCES: 52337836SJohn.Forte@Sun.COM ret = STMF_ERROR_PERM; 52347836SJohn.Forte@Sun.COM break; 52357836SJohn.Forte@Sun.COM case ENOENT: 52367836SJohn.Forte@Sun.COM ret = STMF_ERROR_NOT_FOUND; 52377836SJohn.Forte@Sun.COM break; 52387836SJohn.Forte@Sun.COM default: 52397836SJohn.Forte@Sun.COM syslog(LOG_DEBUG, 52407836SJohn.Forte@Sun.COM "setStmfState:ioctl errno(%d)", errno); 52417836SJohn.Forte@Sun.COM ret = STMF_STATUS_ERROR; 52427836SJohn.Forte@Sun.COM break; 52437836SJohn.Forte@Sun.COM } 52447836SJohn.Forte@Sun.COM } 52457836SJohn.Forte@Sun.COM done: 52467836SJohn.Forte@Sun.COM return (ret); 52477836SJohn.Forte@Sun.COM } 52487836SJohn.Forte@Sun.COM 52497836SJohn.Forte@Sun.COM /* 52507836SJohn.Forte@Sun.COM * stmfOnline 52517836SJohn.Forte@Sun.COM * 52527836SJohn.Forte@Sun.COM * Purpose: Online stmf service 52537836SJohn.Forte@Sun.COM * 52547836SJohn.Forte@Sun.COM */ 52557836SJohn.Forte@Sun.COM int 52567836SJohn.Forte@Sun.COM stmfOnline(void) 52577836SJohn.Forte@Sun.COM { 52587836SJohn.Forte@Sun.COM int ret; 52597836SJohn.Forte@Sun.COM int fd; 52607836SJohn.Forte@Sun.COM stmfState state; 52617836SJohn.Forte@Sun.COM stmf_state_desc_t iState; 52627836SJohn.Forte@Sun.COM 52637836SJohn.Forte@Sun.COM ret = stmfGetState(&state); 52647836SJohn.Forte@Sun.COM if (ret == STMF_STATUS_SUCCESS) { 52657836SJohn.Forte@Sun.COM if (state.operationalState == STMF_SERVICE_STATE_ONLINE) { 52667836SJohn.Forte@Sun.COM return (STMF_ERROR_SERVICE_ONLINE); 52677836SJohn.Forte@Sun.COM } 52687836SJohn.Forte@Sun.COM } else { 52697836SJohn.Forte@Sun.COM return (STMF_STATUS_ERROR); 52707836SJohn.Forte@Sun.COM } 52717836SJohn.Forte@Sun.COM iState.state = STMF_STATE_ONLINE; 52727836SJohn.Forte@Sun.COM iState.config_state = STMF_CONFIG_NONE; 52737836SJohn.Forte@Sun.COM /* 52747836SJohn.Forte@Sun.COM * Open control node for stmf 52757836SJohn.Forte@Sun.COM * to make call to setStmfState() 52767836SJohn.Forte@Sun.COM */ 52777836SJohn.Forte@Sun.COM if ((ret = openStmf(OPEN_EXCL_STMF, &fd)) != STMF_STATUS_SUCCESS) 52787836SJohn.Forte@Sun.COM return (ret); 52797836SJohn.Forte@Sun.COM ret = setStmfState(fd, &iState, STMF_SERVICE_TYPE); 52807836SJohn.Forte@Sun.COM (void) close(fd); 52817836SJohn.Forte@Sun.COM return (ret); 52827836SJohn.Forte@Sun.COM } 52837836SJohn.Forte@Sun.COM 52847836SJohn.Forte@Sun.COM /* 52857836SJohn.Forte@Sun.COM * stmfOffline 52867836SJohn.Forte@Sun.COM * 52877836SJohn.Forte@Sun.COM * Purpose: Offline stmf service 52887836SJohn.Forte@Sun.COM * 52897836SJohn.Forte@Sun.COM */ 52907836SJohn.Forte@Sun.COM int 52917836SJohn.Forte@Sun.COM stmfOffline(void) 52927836SJohn.Forte@Sun.COM { 52937836SJohn.Forte@Sun.COM int ret; 52947836SJohn.Forte@Sun.COM int fd; 52957836SJohn.Forte@Sun.COM stmfState state; 52967836SJohn.Forte@Sun.COM stmf_state_desc_t iState; 52977836SJohn.Forte@Sun.COM 52987836SJohn.Forte@Sun.COM ret = stmfGetState(&state); 52997836SJohn.Forte@Sun.COM if (ret == STMF_STATUS_SUCCESS) { 53007836SJohn.Forte@Sun.COM if (state.operationalState == STMF_SERVICE_STATE_OFFLINE) { 53017836SJohn.Forte@Sun.COM return (STMF_ERROR_SERVICE_OFFLINE); 53027836SJohn.Forte@Sun.COM } 53037836SJohn.Forte@Sun.COM } else { 53047836SJohn.Forte@Sun.COM return (STMF_STATUS_ERROR); 53057836SJohn.Forte@Sun.COM } 53067836SJohn.Forte@Sun.COM iState.state = STMF_STATE_OFFLINE; 53077836SJohn.Forte@Sun.COM iState.config_state = STMF_CONFIG_NONE; 53087836SJohn.Forte@Sun.COM 53097836SJohn.Forte@Sun.COM /* 53107836SJohn.Forte@Sun.COM * Open control node for stmf 53117836SJohn.Forte@Sun.COM * to make call to setStmfState() 53127836SJohn.Forte@Sun.COM */ 53137836SJohn.Forte@Sun.COM if ((ret = openStmf(OPEN_EXCL_STMF, &fd)) != STMF_STATUS_SUCCESS) 53147836SJohn.Forte@Sun.COM return (ret); 53157836SJohn.Forte@Sun.COM ret = setStmfState(fd, &iState, STMF_SERVICE_TYPE); 53167836SJohn.Forte@Sun.COM (void) close(fd); 53177836SJohn.Forte@Sun.COM return (ret); 53187836SJohn.Forte@Sun.COM } 53197836SJohn.Forte@Sun.COM 53207836SJohn.Forte@Sun.COM 53217836SJohn.Forte@Sun.COM /* 53227836SJohn.Forte@Sun.COM * stmfOfflineTarget 53237836SJohn.Forte@Sun.COM * 53247836SJohn.Forte@Sun.COM * Purpose: Change state of target to offline 53257836SJohn.Forte@Sun.COM * 53267836SJohn.Forte@Sun.COM * devid - devid of the target to offline 53277836SJohn.Forte@Sun.COM */ 53287836SJohn.Forte@Sun.COM int 53297836SJohn.Forte@Sun.COM stmfOfflineTarget(stmfDevid *devid) 53307836SJohn.Forte@Sun.COM { 53317836SJohn.Forte@Sun.COM stmf_state_desc_t targetState; 53327836SJohn.Forte@Sun.COM int ret = STMF_STATUS_SUCCESS; 53337836SJohn.Forte@Sun.COM int fd; 53347836SJohn.Forte@Sun.COM 53357836SJohn.Forte@Sun.COM if (devid == NULL) { 53367836SJohn.Forte@Sun.COM return (STMF_ERROR_INVALID_ARG); 53377836SJohn.Forte@Sun.COM } 53387836SJohn.Forte@Sun.COM bzero(&targetState, sizeof (targetState)); 53397836SJohn.Forte@Sun.COM 53407836SJohn.Forte@Sun.COM targetState.state = STMF_STATE_OFFLINE; 53417836SJohn.Forte@Sun.COM targetState.ident[IDENT_LENGTH_BYTE] = devid->identLength; 53427836SJohn.Forte@Sun.COM bcopy(&(devid->ident), &targetState.ident[IDENT_LENGTH_BYTE + 1], 53437836SJohn.Forte@Sun.COM devid->identLength); 53447836SJohn.Forte@Sun.COM /* 53457836SJohn.Forte@Sun.COM * Open control node for stmf 53467836SJohn.Forte@Sun.COM * to make call to setStmfState() 53477836SJohn.Forte@Sun.COM */ 53487836SJohn.Forte@Sun.COM if ((ret = openStmf(OPEN_EXCL_STMF, &fd)) != STMF_STATUS_SUCCESS) 53497836SJohn.Forte@Sun.COM return (ret); 53507836SJohn.Forte@Sun.COM ret = setStmfState(fd, &targetState, TARGET_TYPE); 53517836SJohn.Forte@Sun.COM (void) close(fd); 53527836SJohn.Forte@Sun.COM return (ret); 53537836SJohn.Forte@Sun.COM } 53547836SJohn.Forte@Sun.COM 53557836SJohn.Forte@Sun.COM /* 53567836SJohn.Forte@Sun.COM * stmfOfflineLogicalUnit 53577836SJohn.Forte@Sun.COM * 53587836SJohn.Forte@Sun.COM * Purpose: Change state of logical unit to offline 53597836SJohn.Forte@Sun.COM * 53607836SJohn.Forte@Sun.COM * lu - guid of the logical unit to offline 53617836SJohn.Forte@Sun.COM */ 53627836SJohn.Forte@Sun.COM int 53637836SJohn.Forte@Sun.COM stmfOfflineLogicalUnit(stmfGuid *lu) 53647836SJohn.Forte@Sun.COM { 53657836SJohn.Forte@Sun.COM stmf_state_desc_t luState; 53667836SJohn.Forte@Sun.COM int ret = STMF_STATUS_SUCCESS; 53677836SJohn.Forte@Sun.COM int fd; 53687836SJohn.Forte@Sun.COM 53697836SJohn.Forte@Sun.COM if (lu == NULL) { 53707836SJohn.Forte@Sun.COM return (STMF_ERROR_INVALID_ARG); 53717836SJohn.Forte@Sun.COM } 53727836SJohn.Forte@Sun.COM 53737836SJohn.Forte@Sun.COM bzero(&luState, sizeof (luState)); 53747836SJohn.Forte@Sun.COM 53757836SJohn.Forte@Sun.COM luState.state = STMF_STATE_OFFLINE; 53767836SJohn.Forte@Sun.COM bcopy(lu, &luState.ident, sizeof (stmfGuid)); 53777836SJohn.Forte@Sun.COM /* 53787836SJohn.Forte@Sun.COM * Open control node for stmf 53797836SJohn.Forte@Sun.COM * to make call to setStmfState() 53807836SJohn.Forte@Sun.COM */ 53817836SJohn.Forte@Sun.COM if ((ret = openStmf(OPEN_EXCL_STMF, &fd)) != STMF_STATUS_SUCCESS) 53827836SJohn.Forte@Sun.COM return (ret); 53837836SJohn.Forte@Sun.COM ret = setStmfState(fd, &luState, LOGICAL_UNIT_TYPE); 53847836SJohn.Forte@Sun.COM (void) close(fd); 53857836SJohn.Forte@Sun.COM return (ret); 53867836SJohn.Forte@Sun.COM } 53877836SJohn.Forte@Sun.COM 53887836SJohn.Forte@Sun.COM /* 53897836SJohn.Forte@Sun.COM * stmfOnlineTarget 53907836SJohn.Forte@Sun.COM * 53917836SJohn.Forte@Sun.COM * Purpose: Change state of target to online 53927836SJohn.Forte@Sun.COM * 53937836SJohn.Forte@Sun.COM * devid - devid of the target to online 53947836SJohn.Forte@Sun.COM */ 53957836SJohn.Forte@Sun.COM int 53967836SJohn.Forte@Sun.COM stmfOnlineTarget(stmfDevid *devid) 53977836SJohn.Forte@Sun.COM { 53987836SJohn.Forte@Sun.COM stmf_state_desc_t targetState; 53997836SJohn.Forte@Sun.COM int ret = STMF_STATUS_SUCCESS; 54007836SJohn.Forte@Sun.COM int fd; 54017836SJohn.Forte@Sun.COM 54027836SJohn.Forte@Sun.COM if (devid == NULL) { 54037836SJohn.Forte@Sun.COM return (STMF_ERROR_INVALID_ARG); 54047836SJohn.Forte@Sun.COM } 54057836SJohn.Forte@Sun.COM bzero(&targetState, sizeof (targetState)); 54067836SJohn.Forte@Sun.COM 54077836SJohn.Forte@Sun.COM targetState.state = STMF_STATE_ONLINE; 54087836SJohn.Forte@Sun.COM targetState.ident[IDENT_LENGTH_BYTE] = devid->identLength; 54097836SJohn.Forte@Sun.COM bcopy(&(devid->ident), &targetState.ident[IDENT_LENGTH_BYTE + 1], 54107836SJohn.Forte@Sun.COM devid->identLength); 54117836SJohn.Forte@Sun.COM /* 54127836SJohn.Forte@Sun.COM * Open control node for stmf 54137836SJohn.Forte@Sun.COM * to make call to setStmfState() 54147836SJohn.Forte@Sun.COM */ 54157836SJohn.Forte@Sun.COM if ((ret = openStmf(OPEN_EXCL_STMF, &fd)) != STMF_STATUS_SUCCESS) 54167836SJohn.Forte@Sun.COM return (ret); 54177836SJohn.Forte@Sun.COM ret = setStmfState(fd, &targetState, TARGET_TYPE); 54187836SJohn.Forte@Sun.COM (void) close(fd); 54197836SJohn.Forte@Sun.COM return (ret); 54207836SJohn.Forte@Sun.COM } 54217836SJohn.Forte@Sun.COM 54227836SJohn.Forte@Sun.COM /* 54237836SJohn.Forte@Sun.COM * stmfOnlineLogicalUnit 54247836SJohn.Forte@Sun.COM * 54257836SJohn.Forte@Sun.COM * Purpose: Change state of logical unit to online 54267836SJohn.Forte@Sun.COM * 54277836SJohn.Forte@Sun.COM * lu - guid of the logical unit to online 54287836SJohn.Forte@Sun.COM */ 54297836SJohn.Forte@Sun.COM int 54307836SJohn.Forte@Sun.COM stmfOnlineLogicalUnit(stmfGuid *lu) 54317836SJohn.Forte@Sun.COM { 54327836SJohn.Forte@Sun.COM stmf_state_desc_t luState; 54337836SJohn.Forte@Sun.COM int ret = STMF_STATUS_SUCCESS; 54347836SJohn.Forte@Sun.COM int fd; 54357836SJohn.Forte@Sun.COM 54367836SJohn.Forte@Sun.COM if (lu == NULL) { 54377836SJohn.Forte@Sun.COM return (STMF_ERROR_INVALID_ARG); 54387836SJohn.Forte@Sun.COM } 54397836SJohn.Forte@Sun.COM 54407836SJohn.Forte@Sun.COM bzero(&luState, sizeof (luState)); 54417836SJohn.Forte@Sun.COM 54427836SJohn.Forte@Sun.COM luState.state = STMF_STATE_ONLINE; 54437836SJohn.Forte@Sun.COM bcopy(lu, &luState.ident, sizeof (stmfGuid)); 54447836SJohn.Forte@Sun.COM /* 54457836SJohn.Forte@Sun.COM * Open control node for stmf 54467836SJohn.Forte@Sun.COM * to make call to setStmfState() 54477836SJohn.Forte@Sun.COM */ 54487836SJohn.Forte@Sun.COM if ((ret = openStmf(OPEN_EXCL_STMF, &fd)) != STMF_STATUS_SUCCESS) 54497836SJohn.Forte@Sun.COM return (ret); 54507836SJohn.Forte@Sun.COM ret = setStmfState(fd, &luState, LOGICAL_UNIT_TYPE); 54517836SJohn.Forte@Sun.COM (void) close(fd); 54527836SJohn.Forte@Sun.COM return (ret); 54537836SJohn.Forte@Sun.COM } 54547836SJohn.Forte@Sun.COM 54557836SJohn.Forte@Sun.COM /* 54567836SJohn.Forte@Sun.COM * stmfRemoveFromHostGroup 54577836SJohn.Forte@Sun.COM * 54587836SJohn.Forte@Sun.COM * Purpose: Removes an initiator from an initiator group 54597836SJohn.Forte@Sun.COM * 54607836SJohn.Forte@Sun.COM * hostGroupName - name of an initiator group 54617836SJohn.Forte@Sun.COM * hostName - name of host group member to remove 54627836SJohn.Forte@Sun.COM */ 54637836SJohn.Forte@Sun.COM int 54647836SJohn.Forte@Sun.COM stmfRemoveFromHostGroup(stmfGroupName *hostGroupName, stmfDevid *hostName) 54657836SJohn.Forte@Sun.COM { 54667836SJohn.Forte@Sun.COM int ret; 54677836SJohn.Forte@Sun.COM int fd; 54687836SJohn.Forte@Sun.COM 54697836SJohn.Forte@Sun.COM if (hostGroupName == NULL || 54707836SJohn.Forte@Sun.COM (strnlen((char *)hostGroupName, sizeof (stmfGroupName)) 54717836SJohn.Forte@Sun.COM == sizeof (stmfGroupName)) || hostName == NULL) { 54727836SJohn.Forte@Sun.COM return (STMF_ERROR_INVALID_ARG); 54737836SJohn.Forte@Sun.COM } 54747836SJohn.Forte@Sun.COM 54757836SJohn.Forte@Sun.COM /* call init */ 54767836SJohn.Forte@Sun.COM ret = initializeConfig(); 54777836SJohn.Forte@Sun.COM if (ret != STMF_STATUS_SUCCESS) { 54787836SJohn.Forte@Sun.COM return (ret); 54797836SJohn.Forte@Sun.COM } 54807836SJohn.Forte@Sun.COM 54817836SJohn.Forte@Sun.COM /* 54827836SJohn.Forte@Sun.COM * Open control node for stmf 54837836SJohn.Forte@Sun.COM */ 54847836SJohn.Forte@Sun.COM if ((ret = openStmf(OPEN_STMF, &fd)) != STMF_STATUS_SUCCESS) 54857836SJohn.Forte@Sun.COM return (ret); 54867836SJohn.Forte@Sun.COM 54877836SJohn.Forte@Sun.COM if ((ret = groupMemberIoctl(fd, STMF_IOCTL_REMOVE_HG_ENTRY, 54887836SJohn.Forte@Sun.COM hostGroupName, hostName)) != STMF_STATUS_SUCCESS) { 54897836SJohn.Forte@Sun.COM goto done; 54907836SJohn.Forte@Sun.COM } 54917836SJohn.Forte@Sun.COM 54929585STim.Szeto@Sun.COM if (iGetPersistMethod() == STMF_PERSIST_NONE) { 54939585STim.Szeto@Sun.COM goto done; 54949585STim.Szeto@Sun.COM } 54959585STim.Szeto@Sun.COM 54967836SJohn.Forte@Sun.COM ret = psRemoveHostGroupMember((char *)hostGroupName, 54977836SJohn.Forte@Sun.COM (char *)hostName->ident); 54987836SJohn.Forte@Sun.COM switch (ret) { 54997836SJohn.Forte@Sun.COM case STMF_PS_SUCCESS: 55007836SJohn.Forte@Sun.COM ret = STMF_STATUS_SUCCESS; 55017836SJohn.Forte@Sun.COM break; 55027836SJohn.Forte@Sun.COM case STMF_PS_ERROR_MEMBER_NOT_FOUND: 55037836SJohn.Forte@Sun.COM ret = STMF_ERROR_MEMBER_NOT_FOUND; 55047836SJohn.Forte@Sun.COM break; 55057836SJohn.Forte@Sun.COM case STMF_PS_ERROR_GROUP_NOT_FOUND: 55067836SJohn.Forte@Sun.COM ret = STMF_ERROR_GROUP_NOT_FOUND; 55077836SJohn.Forte@Sun.COM break; 55087836SJohn.Forte@Sun.COM case STMF_PS_ERROR_BUSY: 55097836SJohn.Forte@Sun.COM ret = STMF_ERROR_BUSY; 55107836SJohn.Forte@Sun.COM break; 55117836SJohn.Forte@Sun.COM case STMF_PS_ERROR_SERVICE_NOT_FOUND: 55127836SJohn.Forte@Sun.COM ret = STMF_ERROR_SERVICE_NOT_FOUND; 55137836SJohn.Forte@Sun.COM break; 55147836SJohn.Forte@Sun.COM case STMF_PS_ERROR_VERSION_MISMATCH: 55157836SJohn.Forte@Sun.COM ret = STMF_ERROR_SERVICE_DATA_VERSION; 55167836SJohn.Forte@Sun.COM break; 55177836SJohn.Forte@Sun.COM default: 55187836SJohn.Forte@Sun.COM syslog(LOG_DEBUG, 55197836SJohn.Forte@Sun.COM "stmfRemoveFromHostGroup" 55207836SJohn.Forte@Sun.COM "psRemoveHostGroupMember:error(%d)", ret); 55217836SJohn.Forte@Sun.COM ret = STMF_STATUS_ERROR; 55227836SJohn.Forte@Sun.COM break; 55237836SJohn.Forte@Sun.COM } 55247836SJohn.Forte@Sun.COM 55257836SJohn.Forte@Sun.COM done: 55267836SJohn.Forte@Sun.COM (void) close(fd); 55277836SJohn.Forte@Sun.COM return (ret); 55287836SJohn.Forte@Sun.COM } 55297836SJohn.Forte@Sun.COM 55307836SJohn.Forte@Sun.COM /* 55317836SJohn.Forte@Sun.COM * stmfRemoveFromTargetGroup 55327836SJohn.Forte@Sun.COM * 55337836SJohn.Forte@Sun.COM * Purpose: Removes a local port from a local port group 55347836SJohn.Forte@Sun.COM * 55357836SJohn.Forte@Sun.COM * targetGroupName - name of a target group 55367836SJohn.Forte@Sun.COM * targetName - name of target to remove 55377836SJohn.Forte@Sun.COM */ 55387836SJohn.Forte@Sun.COM int 55397836SJohn.Forte@Sun.COM stmfRemoveFromTargetGroup(stmfGroupName *targetGroupName, stmfDevid *targetName) 55407836SJohn.Forte@Sun.COM { 55417836SJohn.Forte@Sun.COM int ret; 55427836SJohn.Forte@Sun.COM int fd; 55437836SJohn.Forte@Sun.COM 55447836SJohn.Forte@Sun.COM if (targetGroupName == NULL || 55457836SJohn.Forte@Sun.COM (strnlen((char *)targetGroupName, sizeof (stmfGroupName)) 55467836SJohn.Forte@Sun.COM == sizeof (stmfGroupName)) || targetName == NULL) { 55477836SJohn.Forte@Sun.COM return (STMF_ERROR_INVALID_ARG); 55487836SJohn.Forte@Sun.COM } 55497836SJohn.Forte@Sun.COM 55507836SJohn.Forte@Sun.COM /* call init */ 55517836SJohn.Forte@Sun.COM ret = initializeConfig(); 55527836SJohn.Forte@Sun.COM if (ret != STMF_STATUS_SUCCESS) { 55537836SJohn.Forte@Sun.COM return (ret); 55547836SJohn.Forte@Sun.COM } 55557836SJohn.Forte@Sun.COM 55567836SJohn.Forte@Sun.COM /* 55577836SJohn.Forte@Sun.COM * Open control node for stmf 55587836SJohn.Forte@Sun.COM */ 55597836SJohn.Forte@Sun.COM if ((ret = openStmf(OPEN_STMF, &fd)) != STMF_STATUS_SUCCESS) 55607836SJohn.Forte@Sun.COM return (ret); 55617836SJohn.Forte@Sun.COM 55627836SJohn.Forte@Sun.COM if ((ret = groupMemberIoctl(fd, STMF_IOCTL_REMOVE_TG_ENTRY, 55637836SJohn.Forte@Sun.COM targetGroupName, targetName)) != STMF_STATUS_SUCCESS) { 55647836SJohn.Forte@Sun.COM goto done; 55657836SJohn.Forte@Sun.COM } 55667836SJohn.Forte@Sun.COM 55679585STim.Szeto@Sun.COM if (iGetPersistMethod() == STMF_PERSIST_NONE) { 55689585STim.Szeto@Sun.COM goto done; 55699585STim.Szeto@Sun.COM } 55709585STim.Szeto@Sun.COM 55717836SJohn.Forte@Sun.COM ret = psRemoveTargetGroupMember((char *)targetGroupName, 55727836SJohn.Forte@Sun.COM (char *)targetName->ident); 55737836SJohn.Forte@Sun.COM switch (ret) { 55747836SJohn.Forte@Sun.COM case STMF_PS_SUCCESS: 55757836SJohn.Forte@Sun.COM ret = STMF_STATUS_SUCCESS; 55767836SJohn.Forte@Sun.COM break; 55777836SJohn.Forte@Sun.COM case STMF_PS_ERROR_MEMBER_NOT_FOUND: 55787836SJohn.Forte@Sun.COM ret = STMF_ERROR_MEMBER_NOT_FOUND; 55797836SJohn.Forte@Sun.COM break; 55807836SJohn.Forte@Sun.COM case STMF_PS_ERROR_GROUP_NOT_FOUND: 55817836SJohn.Forte@Sun.COM ret = STMF_ERROR_GROUP_NOT_FOUND; 55827836SJohn.Forte@Sun.COM break; 55837836SJohn.Forte@Sun.COM case STMF_PS_ERROR_BUSY: 55847836SJohn.Forte@Sun.COM ret = STMF_ERROR_BUSY; 55857836SJohn.Forte@Sun.COM break; 55867836SJohn.Forte@Sun.COM case STMF_PS_ERROR_SERVICE_NOT_FOUND: 55877836SJohn.Forte@Sun.COM ret = STMF_ERROR_SERVICE_NOT_FOUND; 55887836SJohn.Forte@Sun.COM break; 55897836SJohn.Forte@Sun.COM case STMF_PS_ERROR_VERSION_MISMATCH: 55907836SJohn.Forte@Sun.COM ret = STMF_ERROR_SERVICE_DATA_VERSION; 55917836SJohn.Forte@Sun.COM break; 55927836SJohn.Forte@Sun.COM default: 55937836SJohn.Forte@Sun.COM syslog(LOG_DEBUG, 55947836SJohn.Forte@Sun.COM "stmfRemoveFromTargetGroup" 55957836SJohn.Forte@Sun.COM "psRemoveTargetGroupMember:error(%d)", ret); 55967836SJohn.Forte@Sun.COM ret = STMF_STATUS_ERROR; 55977836SJohn.Forte@Sun.COM break; 55987836SJohn.Forte@Sun.COM } 55997836SJohn.Forte@Sun.COM 56007836SJohn.Forte@Sun.COM done: 56017836SJohn.Forte@Sun.COM (void) close(fd); 56027836SJohn.Forte@Sun.COM return (ret); 56037836SJohn.Forte@Sun.COM } 56047836SJohn.Forte@Sun.COM 56057836SJohn.Forte@Sun.COM /* 56067836SJohn.Forte@Sun.COM * stmfRemoveViewEntry 56077836SJohn.Forte@Sun.COM * 56087836SJohn.Forte@Sun.COM * Purpose: Removes a view entry from a logical unit 56097836SJohn.Forte@Sun.COM * 56107836SJohn.Forte@Sun.COM * lu - guid of lu for which view entry is being removed 56117836SJohn.Forte@Sun.COM * viewEntryIndex - index of view entry to remove 56127836SJohn.Forte@Sun.COM * 56137836SJohn.Forte@Sun.COM */ 56147836SJohn.Forte@Sun.COM int 56157836SJohn.Forte@Sun.COM stmfRemoveViewEntry(stmfGuid *lu, uint32_t viewEntryIndex) 56167836SJohn.Forte@Sun.COM { 56177836SJohn.Forte@Sun.COM int ret = STMF_STATUS_SUCCESS; 56187836SJohn.Forte@Sun.COM int fd; 56197836SJohn.Forte@Sun.COM int ioctlRet; 56207836SJohn.Forte@Sun.COM stmf_iocdata_t stmfIoctl; 56217836SJohn.Forte@Sun.COM stmf_view_op_entry_t ioctlViewEntry; 56227836SJohn.Forte@Sun.COM 56237836SJohn.Forte@Sun.COM if (lu == NULL) { 56247836SJohn.Forte@Sun.COM return (STMF_ERROR_INVALID_ARG); 56257836SJohn.Forte@Sun.COM } 56267836SJohn.Forte@Sun.COM 56277836SJohn.Forte@Sun.COM /* call init */ 56287836SJohn.Forte@Sun.COM ret = initializeConfig(); 56297836SJohn.Forte@Sun.COM if (ret != STMF_STATUS_SUCCESS) { 56307836SJohn.Forte@Sun.COM return (ret); 56317836SJohn.Forte@Sun.COM } 56327836SJohn.Forte@Sun.COM 56337836SJohn.Forte@Sun.COM /* 56347836SJohn.Forte@Sun.COM * Open control node for stmf 56357836SJohn.Forte@Sun.COM */ 56367836SJohn.Forte@Sun.COM if ((ret = openStmf(OPEN_STMF, &fd)) != STMF_STATUS_SUCCESS) 56377836SJohn.Forte@Sun.COM return (ret); 56387836SJohn.Forte@Sun.COM 56397836SJohn.Forte@Sun.COM bzero(&ioctlViewEntry, sizeof (ioctlViewEntry)); 56407836SJohn.Forte@Sun.COM ioctlViewEntry.ve_ndx_valid = B_TRUE; 56417836SJohn.Forte@Sun.COM ioctlViewEntry.ve_ndx = viewEntryIndex; 56427836SJohn.Forte@Sun.COM bcopy(lu, &ioctlViewEntry.ve_guid, sizeof (stmfGuid)); 56437836SJohn.Forte@Sun.COM 56447836SJohn.Forte@Sun.COM bzero(&stmfIoctl, sizeof (stmfIoctl)); 56457836SJohn.Forte@Sun.COM /* 56467836SJohn.Forte@Sun.COM * Issue ioctl to add to the view entry 56477836SJohn.Forte@Sun.COM */ 56487836SJohn.Forte@Sun.COM stmfIoctl.stmf_version = STMF_VERSION_1; 56497836SJohn.Forte@Sun.COM stmfIoctl.stmf_ibuf_size = sizeof (ioctlViewEntry); 56507836SJohn.Forte@Sun.COM stmfIoctl.stmf_ibuf = (uint64_t)(unsigned long)&ioctlViewEntry; 56517836SJohn.Forte@Sun.COM ioctlRet = ioctl(fd, STMF_IOCTL_REMOVE_VIEW_ENTRY, &stmfIoctl); 56527836SJohn.Forte@Sun.COM if (ioctlRet != 0) { 56537836SJohn.Forte@Sun.COM switch (errno) { 56547836SJohn.Forte@Sun.COM case EBUSY: 56557836SJohn.Forte@Sun.COM ret = STMF_ERROR_BUSY; 56567836SJohn.Forte@Sun.COM break; 56579585STim.Szeto@Sun.COM case EPERM: 56589585STim.Szeto@Sun.COM ret = STMF_ERROR_PERM; 56599585STim.Szeto@Sun.COM break; 56607836SJohn.Forte@Sun.COM case EACCES: 56617836SJohn.Forte@Sun.COM switch (stmfIoctl.stmf_error) { 56627836SJohn.Forte@Sun.COM case STMF_IOCERR_UPDATE_NEED_CFG_INIT: 56637836SJohn.Forte@Sun.COM ret = STMF_ERROR_CONFIG_NONE; 56647836SJohn.Forte@Sun.COM break; 56657836SJohn.Forte@Sun.COM default: 56667836SJohn.Forte@Sun.COM ret = STMF_ERROR_PERM; 56677836SJohn.Forte@Sun.COM break; 56687836SJohn.Forte@Sun.COM } 56697836SJohn.Forte@Sun.COM break; 56707836SJohn.Forte@Sun.COM case ENODEV: 56717836SJohn.Forte@Sun.COM case ENOENT: 56727836SJohn.Forte@Sun.COM ret = STMF_ERROR_NOT_FOUND; 56737836SJohn.Forte@Sun.COM break; 56747836SJohn.Forte@Sun.COM default: 56757836SJohn.Forte@Sun.COM syslog(LOG_DEBUG, 56767836SJohn.Forte@Sun.COM "stmfRemoveViewEntry:ioctl errno(%d)", 56777836SJohn.Forte@Sun.COM errno); 56787836SJohn.Forte@Sun.COM ret = STMF_STATUS_ERROR; 56797836SJohn.Forte@Sun.COM break; 56807836SJohn.Forte@Sun.COM } 56817836SJohn.Forte@Sun.COM goto done; 56827836SJohn.Forte@Sun.COM } 56837836SJohn.Forte@Sun.COM 56849585STim.Szeto@Sun.COM if (iGetPersistMethod() == STMF_PERSIST_NONE) { 56859585STim.Szeto@Sun.COM goto done; 56869585STim.Szeto@Sun.COM } 56879585STim.Szeto@Sun.COM 56887836SJohn.Forte@Sun.COM ret = psRemoveViewEntry(lu, viewEntryIndex); 56897836SJohn.Forte@Sun.COM switch (ret) { 56907836SJohn.Forte@Sun.COM case STMF_PS_SUCCESS: 56917836SJohn.Forte@Sun.COM ret = STMF_STATUS_SUCCESS; 56927836SJohn.Forte@Sun.COM break; 56937836SJohn.Forte@Sun.COM case STMF_PS_ERROR_NOT_FOUND: 56947836SJohn.Forte@Sun.COM ret = STMF_ERROR_NOT_FOUND; 56957836SJohn.Forte@Sun.COM break; 56967836SJohn.Forte@Sun.COM case STMF_PS_ERROR_BUSY: 56977836SJohn.Forte@Sun.COM ret = STMF_ERROR_BUSY; 56987836SJohn.Forte@Sun.COM break; 56997836SJohn.Forte@Sun.COM case STMF_PS_ERROR_SERVICE_NOT_FOUND: 57007836SJohn.Forte@Sun.COM ret = STMF_ERROR_SERVICE_NOT_FOUND; 57017836SJohn.Forte@Sun.COM break; 57027836SJohn.Forte@Sun.COM case STMF_PS_ERROR_VERSION_MISMATCH: 57037836SJohn.Forte@Sun.COM ret = STMF_ERROR_SERVICE_DATA_VERSION; 57047836SJohn.Forte@Sun.COM break; 57057836SJohn.Forte@Sun.COM default: 57067836SJohn.Forte@Sun.COM syslog(LOG_DEBUG, 57077836SJohn.Forte@Sun.COM "stmfRemoveViewEntry" "psRemoveViewEntry:error(%d)", 57087836SJohn.Forte@Sun.COM ret); 57097836SJohn.Forte@Sun.COM ret = STMF_STATUS_ERROR; 57107836SJohn.Forte@Sun.COM break; 57117836SJohn.Forte@Sun.COM } 57127836SJohn.Forte@Sun.COM 57137836SJohn.Forte@Sun.COM done: 57147836SJohn.Forte@Sun.COM (void) close(fd); 57157836SJohn.Forte@Sun.COM return (ret); 57167836SJohn.Forte@Sun.COM } 57177836SJohn.Forte@Sun.COM 57187836SJohn.Forte@Sun.COM /* 57197836SJohn.Forte@Sun.COM * stmfSetProviderData 57207836SJohn.Forte@Sun.COM * 57217836SJohn.Forte@Sun.COM * Purpose: set the provider data 57227836SJohn.Forte@Sun.COM * 57237836SJohn.Forte@Sun.COM * providerName - unique name of provider 57247836SJohn.Forte@Sun.COM * nvl - nvlist to set 57257836SJohn.Forte@Sun.COM * providerType - type of provider for which to set data 57267836SJohn.Forte@Sun.COM * STMF_LU_PROVIDER_TYPE 57277836SJohn.Forte@Sun.COM * STMF_PORT_PROVIDER_TYPE 57287836SJohn.Forte@Sun.COM */ 57297836SJohn.Forte@Sun.COM int 57307836SJohn.Forte@Sun.COM stmfSetProviderData(char *providerName, nvlist_t *nvl, int providerType) 57317836SJohn.Forte@Sun.COM { 57327836SJohn.Forte@Sun.COM return (stmfSetProviderDataProt(providerName, nvl, providerType, 57337836SJohn.Forte@Sun.COM NULL)); 57347836SJohn.Forte@Sun.COM } 57357836SJohn.Forte@Sun.COM 57367836SJohn.Forte@Sun.COM /* 57377836SJohn.Forte@Sun.COM * stmfSetProviderDataProt 57387836SJohn.Forte@Sun.COM * 57397836SJohn.Forte@Sun.COM * Purpose: set the provider data 57407836SJohn.Forte@Sun.COM * 57417836SJohn.Forte@Sun.COM * providerName - unique name of provider 57427836SJohn.Forte@Sun.COM * nvl - nvlist to set 57437836SJohn.Forte@Sun.COM * providerType - type of provider for which to set data 57447836SJohn.Forte@Sun.COM * STMF_LU_PROVIDER_TYPE 57457836SJohn.Forte@Sun.COM * STMF_PORT_PROVIDER_TYPE 57467836SJohn.Forte@Sun.COM * setToken - Stale data token returned in the stmfGetProviderDataProt() 57477836SJohn.Forte@Sun.COM * call or NULL. 57487836SJohn.Forte@Sun.COM */ 57497836SJohn.Forte@Sun.COM int 57507836SJohn.Forte@Sun.COM stmfSetProviderDataProt(char *providerName, nvlist_t *nvl, int providerType, 57517836SJohn.Forte@Sun.COM uint64_t *setToken) 57527836SJohn.Forte@Sun.COM { 57537836SJohn.Forte@Sun.COM int ret; 57547836SJohn.Forte@Sun.COM int fd; 57557836SJohn.Forte@Sun.COM 57567836SJohn.Forte@Sun.COM if (providerName == NULL || nvl == NULL) { 57577836SJohn.Forte@Sun.COM return (STMF_ERROR_INVALID_ARG); 57587836SJohn.Forte@Sun.COM } 57597836SJohn.Forte@Sun.COM 57607836SJohn.Forte@Sun.COM if (providerType != STMF_LU_PROVIDER_TYPE && 57617836SJohn.Forte@Sun.COM providerType != STMF_PORT_PROVIDER_TYPE) { 57627836SJohn.Forte@Sun.COM return (STMF_ERROR_INVALID_ARG); 57637836SJohn.Forte@Sun.COM } 57647836SJohn.Forte@Sun.COM 57657836SJohn.Forte@Sun.COM /* call init */ 57667836SJohn.Forte@Sun.COM ret = initializeConfig(); 57677836SJohn.Forte@Sun.COM if (ret != STMF_STATUS_SUCCESS) { 57687836SJohn.Forte@Sun.COM return (ret); 57697836SJohn.Forte@Sun.COM } 57707836SJohn.Forte@Sun.COM 57717836SJohn.Forte@Sun.COM /* 57727836SJohn.Forte@Sun.COM * Open control node for stmf 57737836SJohn.Forte@Sun.COM */ 57747836SJohn.Forte@Sun.COM if ((ret = openStmf(OPEN_STMF, &fd)) != STMF_STATUS_SUCCESS) 57757836SJohn.Forte@Sun.COM return (ret); 57767836SJohn.Forte@Sun.COM 57779585STim.Szeto@Sun.COM ret = setProviderData(fd, providerName, nvl, providerType, setToken); 57787836SJohn.Forte@Sun.COM 57797836SJohn.Forte@Sun.COM (void) close(fd); 57807836SJohn.Forte@Sun.COM 57817836SJohn.Forte@Sun.COM if (ret != STMF_STATUS_SUCCESS) { 57827836SJohn.Forte@Sun.COM goto done; 57837836SJohn.Forte@Sun.COM } 57847836SJohn.Forte@Sun.COM 57859585STim.Szeto@Sun.COM if (iGetPersistMethod() == STMF_PERSIST_NONE) { 57869585STim.Szeto@Sun.COM goto done; 57879585STim.Szeto@Sun.COM } 57889585STim.Szeto@Sun.COM 57897836SJohn.Forte@Sun.COM /* setting driver provider data successful. Now persist it */ 57909585STim.Szeto@Sun.COM ret = psSetProviderData(providerName, nvl, providerType, NULL); 57917836SJohn.Forte@Sun.COM switch (ret) { 57927836SJohn.Forte@Sun.COM case STMF_PS_SUCCESS: 57937836SJohn.Forte@Sun.COM ret = STMF_STATUS_SUCCESS; 57947836SJohn.Forte@Sun.COM break; 57957836SJohn.Forte@Sun.COM case STMF_PS_ERROR_EXISTS: 57967836SJohn.Forte@Sun.COM ret = STMF_ERROR_EXISTS; 57977836SJohn.Forte@Sun.COM break; 57987836SJohn.Forte@Sun.COM case STMF_PS_ERROR_BUSY: 57997836SJohn.Forte@Sun.COM ret = STMF_ERROR_BUSY; 58007836SJohn.Forte@Sun.COM break; 58017836SJohn.Forte@Sun.COM case STMF_PS_ERROR_SERVICE_NOT_FOUND: 58027836SJohn.Forte@Sun.COM ret = STMF_ERROR_SERVICE_NOT_FOUND; 58037836SJohn.Forte@Sun.COM break; 58047836SJohn.Forte@Sun.COM case STMF_PS_ERROR_VERSION_MISMATCH: 58057836SJohn.Forte@Sun.COM ret = STMF_ERROR_SERVICE_DATA_VERSION; 58067836SJohn.Forte@Sun.COM break; 58077836SJohn.Forte@Sun.COM case STMF_PS_ERROR_PROV_DATA_STALE: 58087836SJohn.Forte@Sun.COM ret = STMF_ERROR_PROV_DATA_STALE; 58097836SJohn.Forte@Sun.COM break; 58107836SJohn.Forte@Sun.COM default: 58117836SJohn.Forte@Sun.COM syslog(LOG_DEBUG, 58127836SJohn.Forte@Sun.COM "stmfSetProviderData" 58137836SJohn.Forte@Sun.COM "psSetProviderData:error(%d)", ret); 58147836SJohn.Forte@Sun.COM ret = STMF_STATUS_ERROR; 58157836SJohn.Forte@Sun.COM break; 58167836SJohn.Forte@Sun.COM } 58177836SJohn.Forte@Sun.COM 58187836SJohn.Forte@Sun.COM done: 58197836SJohn.Forte@Sun.COM return (ret); 58207836SJohn.Forte@Sun.COM } 58217836SJohn.Forte@Sun.COM 58227836SJohn.Forte@Sun.COM /* 58239585STim.Szeto@Sun.COM * getProviderData 58249585STim.Szeto@Sun.COM * 58259585STim.Szeto@Sun.COM * Purpose: set the provider data from stmf 58269585STim.Szeto@Sun.COM * 58279585STim.Szeto@Sun.COM * providerName - unique name of provider 58289585STim.Szeto@Sun.COM * nvl - nvlist to load/retrieve 58299585STim.Szeto@Sun.COM * providerType - logical unit or port provider 58309585STim.Szeto@Sun.COM * setToken - returned stale data token 58319585STim.Szeto@Sun.COM */ 58329585STim.Szeto@Sun.COM int 58339585STim.Szeto@Sun.COM getProviderData(char *providerName, nvlist_t **nvl, int providerType, 58349585STim.Szeto@Sun.COM uint64_t *setToken) 58359585STim.Szeto@Sun.COM { 58369585STim.Szeto@Sun.COM int ret = STMF_STATUS_SUCCESS; 58379585STim.Szeto@Sun.COM int fd; 58389585STim.Szeto@Sun.COM int ioctlRet; 58399585STim.Szeto@Sun.COM size_t nvlistSize = ALLOC_PP_DATA_SIZE; 58409585STim.Szeto@Sun.COM int retryCnt = 0; 58419585STim.Szeto@Sun.COM int retryCntMax = MAX_PROVIDER_RETRY; 58429585STim.Szeto@Sun.COM stmf_ppioctl_data_t ppi = {0}, *ppi_out = NULL; 58439585STim.Szeto@Sun.COM boolean_t retry = B_TRUE; 58449585STim.Szeto@Sun.COM stmf_iocdata_t stmfIoctl; 58459585STim.Szeto@Sun.COM 58469585STim.Szeto@Sun.COM if (providerName == NULL) { 58479585STim.Szeto@Sun.COM return (STMF_ERROR_INVALID_ARG); 58489585STim.Szeto@Sun.COM } 58499585STim.Szeto@Sun.COM 58509585STim.Szeto@Sun.COM /* 58519585STim.Szeto@Sun.COM * Open control node for stmf 58529585STim.Szeto@Sun.COM */ 58539585STim.Szeto@Sun.COM if ((ret = openStmf(OPEN_STMF, &fd)) != STMF_STATUS_SUCCESS) 58549585STim.Szeto@Sun.COM return (ret); 58559585STim.Szeto@Sun.COM 58569585STim.Szeto@Sun.COM /* set provider name and provider type */ 58579585STim.Szeto@Sun.COM if (strlcpy(ppi.ppi_name, providerName, 58589585STim.Szeto@Sun.COM sizeof (ppi.ppi_name)) >= 58599585STim.Szeto@Sun.COM sizeof (ppi.ppi_name)) { 58609585STim.Szeto@Sun.COM ret = STMF_ERROR_INVALID_ARG; 58619585STim.Szeto@Sun.COM goto done; 58629585STim.Szeto@Sun.COM } 58639585STim.Szeto@Sun.COM switch (providerType) { 58649585STim.Szeto@Sun.COM case STMF_LU_PROVIDER_TYPE: 58659585STim.Szeto@Sun.COM ppi.ppi_lu_provider = 1; 58669585STim.Szeto@Sun.COM break; 58679585STim.Szeto@Sun.COM case STMF_PORT_PROVIDER_TYPE: 58689585STim.Szeto@Sun.COM ppi.ppi_port_provider = 1; 58699585STim.Szeto@Sun.COM break; 58709585STim.Szeto@Sun.COM default: 58719585STim.Szeto@Sun.COM ret = STMF_ERROR_INVALID_ARG; 58729585STim.Szeto@Sun.COM goto done; 58739585STim.Szeto@Sun.COM } 58749585STim.Szeto@Sun.COM 58759585STim.Szeto@Sun.COM do { 58769585STim.Szeto@Sun.COM /* allocate memory for ioctl */ 58779585STim.Szeto@Sun.COM ppi_out = (stmf_ppioctl_data_t *)calloc(1, nvlistSize + 58789585STim.Szeto@Sun.COM sizeof (stmf_ppioctl_data_t)); 58799585STim.Szeto@Sun.COM if (ppi_out == NULL) { 58809585STim.Szeto@Sun.COM ret = STMF_ERROR_NOMEM; 58819585STim.Szeto@Sun.COM goto done; 58829585STim.Szeto@Sun.COM 58839585STim.Szeto@Sun.COM } 58849585STim.Szeto@Sun.COM 58859585STim.Szeto@Sun.COM /* set the size of the ioctl data to allocated buffer */ 58869585STim.Szeto@Sun.COM ppi.ppi_data_size = nvlistSize; 58879585STim.Szeto@Sun.COM 58889585STim.Szeto@Sun.COM bzero(&stmfIoctl, sizeof (stmfIoctl)); 58899585STim.Szeto@Sun.COM 58909585STim.Szeto@Sun.COM stmfIoctl.stmf_version = STMF_VERSION_1; 58919585STim.Szeto@Sun.COM stmfIoctl.stmf_ibuf_size = sizeof (stmf_ppioctl_data_t); 58929585STim.Szeto@Sun.COM stmfIoctl.stmf_ibuf = (uint64_t)(unsigned long)&ppi; 58939585STim.Szeto@Sun.COM stmfIoctl.stmf_obuf_size = sizeof (stmf_ppioctl_data_t) + 58949585STim.Szeto@Sun.COM nvlistSize; 58959585STim.Szeto@Sun.COM stmfIoctl.stmf_obuf = (uint64_t)(unsigned long)ppi_out; 58969585STim.Szeto@Sun.COM ioctlRet = ioctl(fd, STMF_IOCTL_GET_PP_DATA, &stmfIoctl); 58979585STim.Szeto@Sun.COM if (ioctlRet != 0) { 58989585STim.Szeto@Sun.COM switch (errno) { 58999585STim.Szeto@Sun.COM case EBUSY: 59009585STim.Szeto@Sun.COM ret = STMF_ERROR_BUSY; 59019585STim.Szeto@Sun.COM break; 59029585STim.Szeto@Sun.COM case EPERM: 59039585STim.Szeto@Sun.COM case EACCES: 59049585STim.Szeto@Sun.COM ret = STMF_ERROR_PERM; 59059585STim.Szeto@Sun.COM break; 59069585STim.Szeto@Sun.COM case EINVAL: 59079585STim.Szeto@Sun.COM if (stmfIoctl.stmf_error == 59089585STim.Szeto@Sun.COM STMF_IOCERR_INSUFFICIENT_BUF) { 59099585STim.Szeto@Sun.COM nvlistSize = 59109585STim.Szeto@Sun.COM ppi_out->ppi_data_size; 59119585STim.Szeto@Sun.COM free(ppi_out); 59129585STim.Szeto@Sun.COM ppi_out = NULL; 59139585STim.Szeto@Sun.COM if (retryCnt++ > retryCntMax) { 59149585STim.Szeto@Sun.COM retry = B_FALSE; 59159585STim.Szeto@Sun.COM ret = STMF_ERROR_BUSY; 59169585STim.Szeto@Sun.COM } else { 59179585STim.Szeto@Sun.COM ret = 59189585STim.Szeto@Sun.COM STMF_STATUS_SUCCESS; 59199585STim.Szeto@Sun.COM } 59209585STim.Szeto@Sun.COM } else { 59219585STim.Szeto@Sun.COM syslog(LOG_DEBUG, 59229585STim.Szeto@Sun.COM "getProviderData:ioctl" 59239585STim.Szeto@Sun.COM "unable to retrieve " 59249585STim.Szeto@Sun.COM "nvlist"); 59259585STim.Szeto@Sun.COM ret = STMF_STATUS_ERROR; 59269585STim.Szeto@Sun.COM } 59279585STim.Szeto@Sun.COM break; 59289585STim.Szeto@Sun.COM case ENOENT: 59299585STim.Szeto@Sun.COM ret = STMF_ERROR_NOT_FOUND; 59309585STim.Szeto@Sun.COM break; 59319585STim.Szeto@Sun.COM default: 59329585STim.Szeto@Sun.COM syslog(LOG_DEBUG, 59339585STim.Szeto@Sun.COM "getProviderData:ioctl errno(%d)", 59349585STim.Szeto@Sun.COM errno); 59359585STim.Szeto@Sun.COM ret = STMF_STATUS_ERROR; 59369585STim.Szeto@Sun.COM break; 59379585STim.Szeto@Sun.COM } 59389585STim.Szeto@Sun.COM if (ret != STMF_STATUS_SUCCESS) 59399585STim.Szeto@Sun.COM goto done; 59409585STim.Szeto@Sun.COM } 59419585STim.Szeto@Sun.COM } while (retry && stmfIoctl.stmf_error == STMF_IOCERR_INSUFFICIENT_BUF); 59429585STim.Szeto@Sun.COM 59439585STim.Szeto@Sun.COM if ((ret = nvlist_unpack((char *)ppi_out->ppi_data, 59449585STim.Szeto@Sun.COM ppi_out->ppi_data_size, nvl, 0)) != 0) { 59459585STim.Szeto@Sun.COM ret = STMF_STATUS_ERROR; 59469585STim.Szeto@Sun.COM goto done; 59479585STim.Szeto@Sun.COM } 59489585STim.Szeto@Sun.COM 59499585STim.Szeto@Sun.COM /* caller has asked for new token */ 59509585STim.Szeto@Sun.COM if (setToken) { 59519585STim.Szeto@Sun.COM *setToken = ppi_out->ppi_token; 59529585STim.Szeto@Sun.COM } 59539585STim.Szeto@Sun.COM done: 59549585STim.Szeto@Sun.COM free(ppi_out); 59559585STim.Szeto@Sun.COM (void) close(fd); 59569585STim.Szeto@Sun.COM return (ret); 59579585STim.Szeto@Sun.COM } 59589585STim.Szeto@Sun.COM 59599585STim.Szeto@Sun.COM /* 59607836SJohn.Forte@Sun.COM * setProviderData 59617836SJohn.Forte@Sun.COM * 59629585STim.Szeto@Sun.COM * Purpose: set the provider data in stmf 59637836SJohn.Forte@Sun.COM * 59647836SJohn.Forte@Sun.COM * providerName - unique name of provider 59657836SJohn.Forte@Sun.COM * nvl - nvlist to set 59667836SJohn.Forte@Sun.COM * providerType - logical unit or port provider 59679585STim.Szeto@Sun.COM * setToken - stale data token to check if not NULL 59687836SJohn.Forte@Sun.COM */ 59697836SJohn.Forte@Sun.COM static int 59709585STim.Szeto@Sun.COM setProviderData(int fd, char *providerName, nvlist_t *nvl, int providerType, 59719585STim.Szeto@Sun.COM uint64_t *setToken) 59727836SJohn.Forte@Sun.COM { 59737836SJohn.Forte@Sun.COM int ret = STMF_STATUS_SUCCESS; 59747836SJohn.Forte@Sun.COM int ioctlRet; 59757836SJohn.Forte@Sun.COM size_t nvlistEncodedSize; 59767836SJohn.Forte@Sun.COM stmf_ppioctl_data_t *ppi = NULL; 59779585STim.Szeto@Sun.COM uint64_t outToken; 59787836SJohn.Forte@Sun.COM char *allocatedNvBuffer; 59797836SJohn.Forte@Sun.COM stmf_iocdata_t stmfIoctl; 59807836SJohn.Forte@Sun.COM 59817836SJohn.Forte@Sun.COM if (providerName == NULL) { 59827836SJohn.Forte@Sun.COM return (STMF_ERROR_INVALID_ARG); 59837836SJohn.Forte@Sun.COM } 59847836SJohn.Forte@Sun.COM 59857836SJohn.Forte@Sun.COM /* get size of encoded nvlist */ 59867836SJohn.Forte@Sun.COM if (nvlist_size(nvl, &nvlistEncodedSize, NV_ENCODE_XDR) != 0) { 59877836SJohn.Forte@Sun.COM return (STMF_STATUS_ERROR); 59887836SJohn.Forte@Sun.COM } 59897836SJohn.Forte@Sun.COM 59907836SJohn.Forte@Sun.COM /* allocate memory for ioctl */ 59917836SJohn.Forte@Sun.COM ppi = (stmf_ppioctl_data_t *)calloc(1, nvlistEncodedSize + 59927836SJohn.Forte@Sun.COM sizeof (stmf_ppioctl_data_t)); 59937836SJohn.Forte@Sun.COM if (ppi == NULL) { 59947836SJohn.Forte@Sun.COM return (STMF_ERROR_NOMEM); 59957836SJohn.Forte@Sun.COM } 59967836SJohn.Forte@Sun.COM 59979585STim.Szeto@Sun.COM if (setToken) { 59989585STim.Szeto@Sun.COM ppi->ppi_token_valid = 1; 59999585STim.Szeto@Sun.COM ppi->ppi_token = *setToken; 60009585STim.Szeto@Sun.COM } 60019585STim.Szeto@Sun.COM 60027836SJohn.Forte@Sun.COM allocatedNvBuffer = (char *)&ppi->ppi_data; 60037836SJohn.Forte@Sun.COM if (nvlist_pack(nvl, &allocatedNvBuffer, &nvlistEncodedSize, 60047836SJohn.Forte@Sun.COM NV_ENCODE_XDR, 0) != 0) { 60057836SJohn.Forte@Sun.COM return (STMF_STATUS_ERROR); 60067836SJohn.Forte@Sun.COM } 60077836SJohn.Forte@Sun.COM 60087836SJohn.Forte@Sun.COM /* set provider name and provider type */ 60097836SJohn.Forte@Sun.COM (void) strncpy(ppi->ppi_name, providerName, sizeof (ppi->ppi_name)); 60107836SJohn.Forte@Sun.COM switch (providerType) { 60117836SJohn.Forte@Sun.COM case STMF_LU_PROVIDER_TYPE: 60127836SJohn.Forte@Sun.COM ppi->ppi_lu_provider = 1; 60137836SJohn.Forte@Sun.COM break; 60147836SJohn.Forte@Sun.COM case STMF_PORT_PROVIDER_TYPE: 60157836SJohn.Forte@Sun.COM ppi->ppi_port_provider = 1; 60167836SJohn.Forte@Sun.COM break; 60177836SJohn.Forte@Sun.COM default: 60187836SJohn.Forte@Sun.COM return (STMF_ERROR_INVALID_ARG); 60197836SJohn.Forte@Sun.COM } 60207836SJohn.Forte@Sun.COM 60217836SJohn.Forte@Sun.COM /* set the size of the ioctl data to packed data size */ 60227836SJohn.Forte@Sun.COM ppi->ppi_data_size = nvlistEncodedSize; 60237836SJohn.Forte@Sun.COM 60247836SJohn.Forte@Sun.COM bzero(&stmfIoctl, sizeof (stmfIoctl)); 60257836SJohn.Forte@Sun.COM 60267836SJohn.Forte@Sun.COM stmfIoctl.stmf_version = STMF_VERSION_1; 60277836SJohn.Forte@Sun.COM /* 60287836SJohn.Forte@Sun.COM * Subtracting 8 from the size as that is the size of the last member 60297836SJohn.Forte@Sun.COM * of the structure where the packed data resides 60307836SJohn.Forte@Sun.COM */ 60317836SJohn.Forte@Sun.COM stmfIoctl.stmf_ibuf_size = nvlistEncodedSize + 60327836SJohn.Forte@Sun.COM sizeof (stmf_ppioctl_data_t) - 8; 60337836SJohn.Forte@Sun.COM stmfIoctl.stmf_ibuf = (uint64_t)(unsigned long)ppi; 60349585STim.Szeto@Sun.COM stmfIoctl.stmf_obuf_size = sizeof (uint64_t); 60359585STim.Szeto@Sun.COM stmfIoctl.stmf_obuf = (uint64_t)(unsigned long)&outToken; 60367836SJohn.Forte@Sun.COM ioctlRet = ioctl(fd, STMF_IOCTL_LOAD_PP_DATA, &stmfIoctl); 60377836SJohn.Forte@Sun.COM if (ioctlRet != 0) { 60387836SJohn.Forte@Sun.COM switch (errno) { 60397836SJohn.Forte@Sun.COM case EBUSY: 60407836SJohn.Forte@Sun.COM ret = STMF_ERROR_BUSY; 60417836SJohn.Forte@Sun.COM break; 60429585STim.Szeto@Sun.COM case EPERM: 60437836SJohn.Forte@Sun.COM case EACCES: 60447836SJohn.Forte@Sun.COM ret = STMF_ERROR_PERM; 60457836SJohn.Forte@Sun.COM break; 60469585STim.Szeto@Sun.COM case EINVAL: 60479585STim.Szeto@Sun.COM if (stmfIoctl.stmf_error == 60489585STim.Szeto@Sun.COM STMF_IOCERR_PPD_UPDATED) { 60499585STim.Szeto@Sun.COM ret = STMF_ERROR_PROV_DATA_STALE; 60509585STim.Szeto@Sun.COM } else { 60519585STim.Szeto@Sun.COM ret = STMF_STATUS_ERROR; 60529585STim.Szeto@Sun.COM } 60539585STim.Szeto@Sun.COM break; 60547836SJohn.Forte@Sun.COM default: 60557836SJohn.Forte@Sun.COM syslog(LOG_DEBUG, 60567836SJohn.Forte@Sun.COM "setProviderData:ioctl errno(%d)", errno); 60577836SJohn.Forte@Sun.COM ret = STMF_STATUS_ERROR; 60587836SJohn.Forte@Sun.COM break; 60597836SJohn.Forte@Sun.COM } 60607836SJohn.Forte@Sun.COM if (ret != STMF_STATUS_SUCCESS) 60617836SJohn.Forte@Sun.COM goto done; 60627836SJohn.Forte@Sun.COM } 60637836SJohn.Forte@Sun.COM 60649585STim.Szeto@Sun.COM /* caller has asked for new token */ 60659585STim.Szeto@Sun.COM if (setToken) { 60669585STim.Szeto@Sun.COM *setToken = outToken; 60679585STim.Szeto@Sun.COM } 60687836SJohn.Forte@Sun.COM done: 60697836SJohn.Forte@Sun.COM free(ppi); 60707836SJohn.Forte@Sun.COM return (ret); 60717836SJohn.Forte@Sun.COM } 60729585STim.Szeto@Sun.COM 60739585STim.Szeto@Sun.COM /* 60749585STim.Szeto@Sun.COM * set the persistence method in the library only or library and service 60759585STim.Szeto@Sun.COM */ 60769585STim.Szeto@Sun.COM int 60779585STim.Szeto@Sun.COM stmfSetPersistMethod(uint8_t persistType, boolean_t serviceSet) 60789585STim.Szeto@Sun.COM { 60799585STim.Szeto@Sun.COM int ret = STMF_STATUS_SUCCESS; 60809585STim.Szeto@Sun.COM int oldPersist; 60819585STim.Szeto@Sun.COM 60829585STim.Szeto@Sun.COM (void) pthread_mutex_lock(&persistenceTypeLock); 60839585STim.Szeto@Sun.COM oldPersist = iPersistType; 60849585STim.Szeto@Sun.COM if (persistType == STMF_PERSIST_NONE || 60859585STim.Szeto@Sun.COM persistType == STMF_PERSIST_SMF) { 60869585STim.Szeto@Sun.COM iLibSetPersist = B_TRUE; 60879585STim.Szeto@Sun.COM iPersistType = persistType; 60889585STim.Szeto@Sun.COM } else { 60899585STim.Szeto@Sun.COM (void) pthread_mutex_unlock(&persistenceTypeLock); 60909585STim.Szeto@Sun.COM return (STMF_ERROR_INVALID_ARG); 60919585STim.Szeto@Sun.COM } 60929585STim.Szeto@Sun.COM /* Is this for this library open or in SMF */ 60939585STim.Szeto@Sun.COM if (serviceSet == B_TRUE) { 60949585STim.Szeto@Sun.COM ret = psSetServicePersist(persistType); 60959585STim.Szeto@Sun.COM if (ret != STMF_PS_SUCCESS) { 60969585STim.Szeto@Sun.COM ret = STMF_ERROR_PERSIST_TYPE; 60979585STim.Szeto@Sun.COM /* Set to old value */ 60989585STim.Szeto@Sun.COM iPersistType = oldPersist; 60999585STim.Szeto@Sun.COM } 61009585STim.Szeto@Sun.COM } 61019585STim.Szeto@Sun.COM (void) pthread_mutex_unlock(&persistenceTypeLock); 61029585STim.Szeto@Sun.COM 61039585STim.Szeto@Sun.COM return (ret); 61049585STim.Szeto@Sun.COM } 61059585STim.Szeto@Sun.COM 61069585STim.Szeto@Sun.COM /* 61079585STim.Szeto@Sun.COM * Only returns internal state for persist. If unset, goes to ps. If that 61089585STim.Szeto@Sun.COM * fails, returns default setting 61099585STim.Szeto@Sun.COM */ 61109585STim.Szeto@Sun.COM static uint8_t 61119585STim.Szeto@Sun.COM iGetPersistMethod() 61129585STim.Szeto@Sun.COM { 61139585STim.Szeto@Sun.COM 61149585STim.Szeto@Sun.COM uint8_t persistType = 0; 61159585STim.Szeto@Sun.COM 61169585STim.Szeto@Sun.COM (void) pthread_mutex_lock(&persistenceTypeLock); 61179585STim.Szeto@Sun.COM if (iLibSetPersist) { 61189585STim.Szeto@Sun.COM persistType = iPersistType; 61199585STim.Szeto@Sun.COM } else { 61209585STim.Szeto@Sun.COM int ret; 61219585STim.Szeto@Sun.COM ret = psGetServicePersist(&persistType); 61229585STim.Szeto@Sun.COM if (ret != STMF_PS_SUCCESS) { 61239585STim.Szeto@Sun.COM /* set to default */ 61249585STim.Szeto@Sun.COM persistType = STMF_DEFAULT_PERSIST; 61259585STim.Szeto@Sun.COM } 61269585STim.Szeto@Sun.COM } 61279585STim.Szeto@Sun.COM (void) pthread_mutex_unlock(&persistenceTypeLock); 61289585STim.Szeto@Sun.COM return (persistType); 61299585STim.Szeto@Sun.COM } 61309585STim.Szeto@Sun.COM 61319585STim.Szeto@Sun.COM /* 61329585STim.Szeto@Sun.COM * Returns either library state or persistent config state depending on 61339585STim.Szeto@Sun.COM * serviceState 61349585STim.Szeto@Sun.COM */ 61359585STim.Szeto@Sun.COM int 61369585STim.Szeto@Sun.COM stmfGetPersistMethod(uint8_t *persistType, boolean_t serviceState) 61379585STim.Szeto@Sun.COM { 61389585STim.Szeto@Sun.COM int ret = STMF_STATUS_SUCCESS; 61399585STim.Szeto@Sun.COM 61409585STim.Szeto@Sun.COM if (persistType == NULL) { 61419585STim.Szeto@Sun.COM return (STMF_ERROR_INVALID_ARG); 61429585STim.Szeto@Sun.COM } 61439585STim.Szeto@Sun.COM if (serviceState) { 61449585STim.Szeto@Sun.COM ret = psGetServicePersist(persistType); 61459585STim.Szeto@Sun.COM if (ret != STMF_PS_SUCCESS) { 61469585STim.Szeto@Sun.COM ret = STMF_ERROR_PERSIST_TYPE; 61479585STim.Szeto@Sun.COM } 61489585STim.Szeto@Sun.COM } else { 61499585STim.Szeto@Sun.COM (void) pthread_mutex_lock(&persistenceTypeLock); 61509585STim.Szeto@Sun.COM if (iLibSetPersist) { 61519585STim.Szeto@Sun.COM *persistType = iPersistType; 61529585STim.Szeto@Sun.COM } else { 61539585STim.Szeto@Sun.COM *persistType = STMF_DEFAULT_PERSIST; 61549585STim.Szeto@Sun.COM } 61559585STim.Szeto@Sun.COM (void) pthread_mutex_unlock(&persistenceTypeLock); 61569585STim.Szeto@Sun.COM } 61579585STim.Szeto@Sun.COM 61589585STim.Szeto@Sun.COM return (ret); 61599585STim.Szeto@Sun.COM } 616010691STim.Szeto@Sun.COM 616110691STim.Szeto@Sun.COM /* 6162*10725SJohn.Forte@Sun.COM * stmfPostProxyMsg 6163*10725SJohn.Forte@Sun.COM * 6164*10725SJohn.Forte@Sun.COM * Purpose: Post a message to the proxy port provider 6165*10725SJohn.Forte@Sun.COM * 6166*10725SJohn.Forte@Sun.COM * buf - buffer containing message to post 6167*10725SJohn.Forte@Sun.COM * buflen - buffer length 6168*10725SJohn.Forte@Sun.COM */ 6169*10725SJohn.Forte@Sun.COM int 6170*10725SJohn.Forte@Sun.COM stmfPostProxyMsg(int hdl, void *buf, uint32_t buflen) 6171*10725SJohn.Forte@Sun.COM { 6172*10725SJohn.Forte@Sun.COM int ret = STMF_STATUS_SUCCESS; 6173*10725SJohn.Forte@Sun.COM int ioctlRet; 6174*10725SJohn.Forte@Sun.COM pppt_iocdata_t ppptIoctl = {0}; 6175*10725SJohn.Forte@Sun.COM 6176*10725SJohn.Forte@Sun.COM if (buf == NULL) { 6177*10725SJohn.Forte@Sun.COM return (STMF_ERROR_INVALID_ARG); 6178*10725SJohn.Forte@Sun.COM } 6179*10725SJohn.Forte@Sun.COM 6180*10725SJohn.Forte@Sun.COM /* 6181*10725SJohn.Forte@Sun.COM * Issue ioctl to post the message 6182*10725SJohn.Forte@Sun.COM */ 6183*10725SJohn.Forte@Sun.COM ppptIoctl.pppt_version = PPPT_VERSION_1; 6184*10725SJohn.Forte@Sun.COM ppptIoctl.pppt_buf_size = buflen; 6185*10725SJohn.Forte@Sun.COM ppptIoctl.pppt_buf = (uint64_t)(unsigned long)buf; 6186*10725SJohn.Forte@Sun.COM ioctlRet = ioctl(hdl, PPPT_MESSAGE, &ppptIoctl); 6187*10725SJohn.Forte@Sun.COM if (ioctlRet != 0) { 6188*10725SJohn.Forte@Sun.COM switch (errno) { 6189*10725SJohn.Forte@Sun.COM case EPERM: 6190*10725SJohn.Forte@Sun.COM case EACCES: 6191*10725SJohn.Forte@Sun.COM ret = STMF_ERROR_PERM; 6192*10725SJohn.Forte@Sun.COM break; 6193*10725SJohn.Forte@Sun.COM default: 6194*10725SJohn.Forte@Sun.COM ret = STMF_ERROR_POST_MSG_FAILED; 6195*10725SJohn.Forte@Sun.COM break; 6196*10725SJohn.Forte@Sun.COM } 6197*10725SJohn.Forte@Sun.COM } 6198*10725SJohn.Forte@Sun.COM 6199*10725SJohn.Forte@Sun.COM return (ret); 6200*10725SJohn.Forte@Sun.COM } 6201*10725SJohn.Forte@Sun.COM 6202*10725SJohn.Forte@Sun.COM /* 6203*10725SJohn.Forte@Sun.COM * stmfInitProxyDoor 6204*10725SJohn.Forte@Sun.COM * 6205*10725SJohn.Forte@Sun.COM * Purpose: Install door in proxy 6206*10725SJohn.Forte@Sun.COM * 6207*10725SJohn.Forte@Sun.COM * hdl - pointer to returned handle 6208*10725SJohn.Forte@Sun.COM * fd - door from door_create() 6209*10725SJohn.Forte@Sun.COM */ 6210*10725SJohn.Forte@Sun.COM int 6211*10725SJohn.Forte@Sun.COM stmfInitProxyDoor(int *hdl, int door) 6212*10725SJohn.Forte@Sun.COM { 6213*10725SJohn.Forte@Sun.COM int ret = STMF_STATUS_SUCCESS; 6214*10725SJohn.Forte@Sun.COM int ioctlRet; 6215*10725SJohn.Forte@Sun.COM int fd; 6216*10725SJohn.Forte@Sun.COM pppt_iocdata_t ppptIoctl = {0}; 6217*10725SJohn.Forte@Sun.COM 6218*10725SJohn.Forte@Sun.COM if (hdl == NULL) { 6219*10725SJohn.Forte@Sun.COM return (STMF_ERROR_INVALID_ARG); 6220*10725SJohn.Forte@Sun.COM } 6221*10725SJohn.Forte@Sun.COM 6222*10725SJohn.Forte@Sun.COM /* 6223*10725SJohn.Forte@Sun.COM * Open control node for pppt 6224*10725SJohn.Forte@Sun.COM */ 6225*10725SJohn.Forte@Sun.COM if ((ret = openPppt(OPEN_PPPT, &fd)) != STMF_STATUS_SUCCESS) { 6226*10725SJohn.Forte@Sun.COM return (ret); 6227*10725SJohn.Forte@Sun.COM } 6228*10725SJohn.Forte@Sun.COM 6229*10725SJohn.Forte@Sun.COM /* 6230*10725SJohn.Forte@Sun.COM * Issue ioctl to install the door 6231*10725SJohn.Forte@Sun.COM */ 6232*10725SJohn.Forte@Sun.COM ppptIoctl.pppt_version = PPPT_VERSION_1; 6233*10725SJohn.Forte@Sun.COM ppptIoctl.pppt_door_fd = (uint32_t)door; 6234*10725SJohn.Forte@Sun.COM ioctlRet = ioctl(fd, PPPT_INSTALL_DOOR, &ppptIoctl); 6235*10725SJohn.Forte@Sun.COM if (ioctlRet != 0) { 6236*10725SJohn.Forte@Sun.COM switch (errno) { 6237*10725SJohn.Forte@Sun.COM case EPERM: 6238*10725SJohn.Forte@Sun.COM case EACCES: 6239*10725SJohn.Forte@Sun.COM ret = STMF_ERROR_PERM; 6240*10725SJohn.Forte@Sun.COM break; 6241*10725SJohn.Forte@Sun.COM case EINVAL: 6242*10725SJohn.Forte@Sun.COM ret = STMF_ERROR_INVALID_ARG; 6243*10725SJohn.Forte@Sun.COM break; 6244*10725SJohn.Forte@Sun.COM case EBUSY: 6245*10725SJohn.Forte@Sun.COM ret = STMF_ERROR_DOOR_INSTALLED; 6246*10725SJohn.Forte@Sun.COM break; 6247*10725SJohn.Forte@Sun.COM default: 6248*10725SJohn.Forte@Sun.COM ret = STMF_STATUS_ERROR; 6249*10725SJohn.Forte@Sun.COM break; 6250*10725SJohn.Forte@Sun.COM } 6251*10725SJohn.Forte@Sun.COM } 6252*10725SJohn.Forte@Sun.COM 6253*10725SJohn.Forte@Sun.COM /* return driver fd to caller */ 6254*10725SJohn.Forte@Sun.COM *hdl = fd; 6255*10725SJohn.Forte@Sun.COM return (ret); 6256*10725SJohn.Forte@Sun.COM } 6257*10725SJohn.Forte@Sun.COM 6258*10725SJohn.Forte@Sun.COM void 6259*10725SJohn.Forte@Sun.COM stmfDestroyProxyDoor(int hdl) 6260*10725SJohn.Forte@Sun.COM { 6261*10725SJohn.Forte@Sun.COM (void) close(hdl); 6262*10725SJohn.Forte@Sun.COM } 6263*10725SJohn.Forte@Sun.COM 6264*10725SJohn.Forte@Sun.COM /* 626510691STim.Szeto@Sun.COM * validateLunNumIoctl 626610691STim.Szeto@Sun.COM * 626710691STim.Szeto@Sun.COM * Purpose: Issues ioctl to check and get available lun# in view entry 626810691STim.Szeto@Sun.COM * 626910691STim.Szeto@Sun.COM * viewEntry - view entry to use 627010691STim.Szeto@Sun.COM */ 627110691STim.Szeto@Sun.COM static int 627210691STim.Szeto@Sun.COM validateLunNumIoctl(int fd, stmfViewEntry *viewEntry) 627310691STim.Szeto@Sun.COM { 627410691STim.Szeto@Sun.COM int ret = STMF_STATUS_SUCCESS; 627510691STim.Szeto@Sun.COM int ioctlRet; 627610691STim.Szeto@Sun.COM stmf_iocdata_t stmfIoctl; 627710691STim.Szeto@Sun.COM stmf_view_op_entry_t ioctlViewEntry; 627810691STim.Szeto@Sun.COM 627910691STim.Szeto@Sun.COM bzero(&ioctlViewEntry, sizeof (ioctlViewEntry)); 628010691STim.Szeto@Sun.COM /* 628110691STim.Szeto@Sun.COM * don't set ve_ndx or ve_ndx_valid as ve_ndx_valid should be 628210691STim.Szeto@Sun.COM * false on input 628310691STim.Szeto@Sun.COM */ 628410691STim.Szeto@Sun.COM ioctlViewEntry.ve_lu_number_valid = viewEntry->luNbrValid; 628510691STim.Szeto@Sun.COM ioctlViewEntry.ve_all_hosts = viewEntry->allHosts; 628610691STim.Szeto@Sun.COM ioctlViewEntry.ve_all_targets = viewEntry->allTargets; 628710691STim.Szeto@Sun.COM 628810691STim.Szeto@Sun.COM if (viewEntry->allHosts == B_FALSE) { 628910691STim.Szeto@Sun.COM bcopy(viewEntry->hostGroup, &ioctlViewEntry.ve_host_group.name, 629010691STim.Szeto@Sun.COM sizeof (stmfGroupName)); 629110691STim.Szeto@Sun.COM ioctlViewEntry.ve_host_group.name_size = 629210691STim.Szeto@Sun.COM strlen((char *)viewEntry->hostGroup); 629310691STim.Szeto@Sun.COM } 629410691STim.Szeto@Sun.COM if (viewEntry->allTargets == B_FALSE) { 629510691STim.Szeto@Sun.COM bcopy(viewEntry->targetGroup, 629610691STim.Szeto@Sun.COM &ioctlViewEntry.ve_target_group.name, 629710691STim.Szeto@Sun.COM sizeof (stmfGroupName)); 629810691STim.Szeto@Sun.COM ioctlViewEntry.ve_target_group.name_size = 629910691STim.Szeto@Sun.COM strlen((char *)viewEntry->targetGroup); 630010691STim.Szeto@Sun.COM } 630110691STim.Szeto@Sun.COM /* Validating the lun number */ 630210691STim.Szeto@Sun.COM if (viewEntry->luNbrValid) { 630310691STim.Szeto@Sun.COM bcopy(viewEntry->luNbr, &ioctlViewEntry.ve_lu_nbr, 630410691STim.Szeto@Sun.COM sizeof (ioctlViewEntry.ve_lu_nbr)); 630510691STim.Szeto@Sun.COM } 630610691STim.Szeto@Sun.COM 630710691STim.Szeto@Sun.COM bzero(&stmfIoctl, sizeof (stmfIoctl)); 630810691STim.Szeto@Sun.COM /* 630910691STim.Szeto@Sun.COM * Issue ioctl to validate lun# in the view entry 631010691STim.Szeto@Sun.COM */ 631110691STim.Szeto@Sun.COM stmfIoctl.stmf_version = STMF_VERSION_1; 631210691STim.Szeto@Sun.COM stmfIoctl.stmf_ibuf_size = sizeof (ioctlViewEntry); 631310691STim.Szeto@Sun.COM stmfIoctl.stmf_ibuf = (uint64_t)(unsigned long)&ioctlViewEntry; 631410691STim.Szeto@Sun.COM stmfIoctl.stmf_obuf_size = sizeof (ioctlViewEntry); 631510691STim.Szeto@Sun.COM stmfIoctl.stmf_obuf = (uint64_t)(unsigned long)&ioctlViewEntry; 631610691STim.Szeto@Sun.COM ioctlRet = ioctl(fd, STMF_IOCTL_VALIDATE_VIEW, &stmfIoctl); 631710691STim.Szeto@Sun.COM 631810691STim.Szeto@Sun.COM /* save available lun number */ 631910691STim.Szeto@Sun.COM if (!viewEntry->luNbrValid) { 632010691STim.Szeto@Sun.COM bcopy(ioctlViewEntry.ve_lu_nbr, viewEntry->luNbr, 632110691STim.Szeto@Sun.COM sizeof (ioctlViewEntry.ve_lu_nbr)); 632210691STim.Szeto@Sun.COM } 632310691STim.Szeto@Sun.COM if (ioctlRet != 0) { 632410691STim.Szeto@Sun.COM switch (errno) { 632510691STim.Szeto@Sun.COM case EBUSY: 632610691STim.Szeto@Sun.COM ret = STMF_ERROR_BUSY; 632710691STim.Szeto@Sun.COM break; 632810691STim.Szeto@Sun.COM case EPERM: 632910691STim.Szeto@Sun.COM ret = STMF_ERROR_PERM; 633010691STim.Szeto@Sun.COM break; 633110691STim.Szeto@Sun.COM case EACCES: 633210691STim.Szeto@Sun.COM switch (stmfIoctl.stmf_error) { 633310691STim.Szeto@Sun.COM case STMF_IOCERR_UPDATE_NEED_CFG_INIT: 633410691STim.Szeto@Sun.COM ret = STMF_ERROR_CONFIG_NONE; 633510691STim.Szeto@Sun.COM break; 633610691STim.Szeto@Sun.COM default: 633710691STim.Szeto@Sun.COM ret = STMF_ERROR_PERM; 633810691STim.Szeto@Sun.COM break; 633910691STim.Szeto@Sun.COM } 634010691STim.Szeto@Sun.COM break; 634110691STim.Szeto@Sun.COM default: 634210691STim.Szeto@Sun.COM switch (stmfIoctl.stmf_error) { 634310691STim.Szeto@Sun.COM case STMF_IOCERR_LU_NUMBER_IN_USE: 634410691STim.Szeto@Sun.COM ret = STMF_ERROR_LUN_IN_USE; 634510691STim.Szeto@Sun.COM break; 634610691STim.Szeto@Sun.COM case STMF_IOCERR_VIEW_ENTRY_CONFLICT: 634710691STim.Szeto@Sun.COM ret = STMF_ERROR_VE_CONFLICT; 634810691STim.Szeto@Sun.COM break; 634910691STim.Szeto@Sun.COM case STMF_IOCERR_UPDATE_NEED_CFG_INIT: 635010691STim.Szeto@Sun.COM ret = STMF_ERROR_CONFIG_NONE; 635110691STim.Szeto@Sun.COM break; 635210691STim.Szeto@Sun.COM case STMF_IOCERR_INVALID_HG: 635310691STim.Szeto@Sun.COM ret = STMF_ERROR_INVALID_HG; 635410691STim.Szeto@Sun.COM break; 635510691STim.Szeto@Sun.COM case STMF_IOCERR_INVALID_TG: 635610691STim.Szeto@Sun.COM ret = STMF_ERROR_INVALID_TG; 635710691STim.Szeto@Sun.COM break; 635810691STim.Szeto@Sun.COM default: 635910691STim.Szeto@Sun.COM syslog(LOG_DEBUG, 636010691STim.Szeto@Sun.COM "addViewEntryIoctl" 636110691STim.Szeto@Sun.COM ":error(%d)", 636210691STim.Szeto@Sun.COM stmfIoctl.stmf_error); 636310691STim.Szeto@Sun.COM ret = STMF_STATUS_ERROR; 636410691STim.Szeto@Sun.COM break; 636510691STim.Szeto@Sun.COM } 636610691STim.Szeto@Sun.COM break; 636710691STim.Szeto@Sun.COM } 636810691STim.Szeto@Sun.COM } 636910691STim.Szeto@Sun.COM return (ret); 637010691STim.Szeto@Sun.COM } 637110691STim.Szeto@Sun.COM 637210691STim.Szeto@Sun.COM /* 637310691STim.Szeto@Sun.COM * stmfValidateView 637410691STim.Szeto@Sun.COM * 637510691STim.Szeto@Sun.COM * Purpose: Validate or get lun # base on TG, HG of view entry 637610691STim.Szeto@Sun.COM * 637710691STim.Szeto@Sun.COM * viewEntry - view entry structure to use 637810691STim.Szeto@Sun.COM */ 637910691STim.Szeto@Sun.COM int 638010691STim.Szeto@Sun.COM stmfValidateView(stmfViewEntry *viewEntry) 638110691STim.Szeto@Sun.COM { 638210691STim.Szeto@Sun.COM int ret; 638310691STim.Szeto@Sun.COM int fd; 638410691STim.Szeto@Sun.COM stmfViewEntry iViewEntry; 638510691STim.Szeto@Sun.COM 638610691STim.Szeto@Sun.COM if (viewEntry == NULL) { 638710691STim.Szeto@Sun.COM return (STMF_ERROR_INVALID_ARG); 638810691STim.Szeto@Sun.COM } 638910691STim.Szeto@Sun.COM 639010691STim.Szeto@Sun.COM /* initialize and set internal view entry */ 639110691STim.Szeto@Sun.COM bzero(&iViewEntry, sizeof (iViewEntry)); 639210691STim.Szeto@Sun.COM 639310691STim.Szeto@Sun.COM if (!viewEntry->allHosts) { 639410691STim.Szeto@Sun.COM bcopy(viewEntry->hostGroup, iViewEntry.hostGroup, 639510691STim.Szeto@Sun.COM sizeof (iViewEntry.hostGroup)); 639610691STim.Szeto@Sun.COM } else { 639710691STim.Szeto@Sun.COM iViewEntry.allHosts = B_TRUE; 639810691STim.Szeto@Sun.COM } 639910691STim.Szeto@Sun.COM 640010691STim.Szeto@Sun.COM if (!viewEntry->allTargets) { 640110691STim.Szeto@Sun.COM bcopy(viewEntry->targetGroup, iViewEntry.targetGroup, 640210691STim.Szeto@Sun.COM sizeof (iViewEntry.targetGroup)); 640310691STim.Szeto@Sun.COM } else { 640410691STim.Szeto@Sun.COM iViewEntry.allTargets = B_TRUE; 640510691STim.Szeto@Sun.COM } 640610691STim.Szeto@Sun.COM 640710691STim.Szeto@Sun.COM if (viewEntry->luNbrValid) { 640810691STim.Szeto@Sun.COM iViewEntry.luNbrValid = B_TRUE; 640910691STim.Szeto@Sun.COM bcopy(viewEntry->luNbr, iViewEntry.luNbr, 641010691STim.Szeto@Sun.COM sizeof (iViewEntry.luNbr)); 641110691STim.Szeto@Sun.COM } 641210691STim.Szeto@Sun.COM 641310691STim.Szeto@Sun.COM /* 641410691STim.Szeto@Sun.COM * set users return view entry index valid flag to false 641510691STim.Szeto@Sun.COM * in case of failure 641610691STim.Szeto@Sun.COM */ 641710691STim.Szeto@Sun.COM viewEntry->veIndexValid = B_FALSE; 641810691STim.Szeto@Sun.COM 641910691STim.Szeto@Sun.COM /* Check to ensure service exists */ 642010691STim.Szeto@Sun.COM if (psCheckService() != STMF_STATUS_SUCCESS) { 642110691STim.Szeto@Sun.COM return (STMF_ERROR_SERVICE_NOT_FOUND); 642210691STim.Szeto@Sun.COM } 642310691STim.Szeto@Sun.COM 642410691STim.Szeto@Sun.COM /* call init */ 642510691STim.Szeto@Sun.COM ret = initializeConfig(); 642610691STim.Szeto@Sun.COM if (ret != STMF_STATUS_SUCCESS) { 642710691STim.Szeto@Sun.COM return (ret); 642810691STim.Szeto@Sun.COM } 642910691STim.Szeto@Sun.COM 643010691STim.Szeto@Sun.COM /* 643110691STim.Szeto@Sun.COM * Open control node for stmf 643210691STim.Szeto@Sun.COM */ 643310691STim.Szeto@Sun.COM if ((ret = openStmf(OPEN_STMF, &fd)) != STMF_STATUS_SUCCESS) 643410691STim.Szeto@Sun.COM return (ret); 643510691STim.Szeto@Sun.COM 643610691STim.Szeto@Sun.COM /* 643710691STim.Szeto@Sun.COM * Validate lun# in the view entry from the driver 643810691STim.Szeto@Sun.COM */ 643910691STim.Szeto@Sun.COM ret = validateLunNumIoctl(fd, &iViewEntry); 644010691STim.Szeto@Sun.COM (void) close(fd); 644110691STim.Szeto@Sun.COM 644210691STim.Szeto@Sun.COM /* save available lun number */ 644310691STim.Szeto@Sun.COM if (!viewEntry->luNbrValid) { 644410691STim.Szeto@Sun.COM bcopy(iViewEntry.luNbr, viewEntry->luNbr, 644510691STim.Szeto@Sun.COM sizeof (iViewEntry.luNbr)); 644610691STim.Szeto@Sun.COM } 644710691STim.Szeto@Sun.COM 644810691STim.Szeto@Sun.COM return (ret); 644910691STim.Szeto@Sun.COM } 6450