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