Mercurial > illumos > illumos-gate
changeset 11103:3b3f33a37cab
6894418 set interface for global logical unit property
6895461 'stmf: WARNING: proxy port not registered' appears occasionally on COMSTAR target
author | John Forte <John.Forte@Sun.COM> |
---|---|
date | Thu, 19 Nov 2009 05:07:17 -0800 |
parents | b91faef0c984 |
children | 166a083c78c5 |
files | usr/src/lib/libstmf/common/libstmf.h usr/src/lib/libstmf/common/mapfile-vers usr/src/lib/libstmf/common/stmf.c usr/src/uts/common/io/comstar/lu/stmf_sbd/sbd.c usr/src/uts/common/io/comstar/lu/stmf_sbd/sbd_scsi.c usr/src/uts/common/io/comstar/lu/stmf_sbd/stmf_sbd.h usr/src/uts/common/io/comstar/stmf/stmf.c usr/src/uts/common/sys/stmf_sbd_ioctl.h |
diffstat | 8 files changed, 451 insertions(+), 10 deletions(-) [+] |
line wrap: on
line diff
--- a/usr/src/lib/libstmf/common/libstmf.h Thu Nov 19 15:28:11 2009 +1100 +++ b/usr/src/lib/libstmf/common/libstmf.h Thu Nov 19 05:07:17 2009 -0800 @@ -323,6 +323,8 @@ int stmfFreeLuResource(luResource hdl); void stmfFreeMemory(void *); int stmfGetAluaState(boolean_t *enabled, uint32_t *node); +int stmfGetGlobalLuProp(uint16_t dType, uint32_t prop, char *propVal, + size_t *propLen); int stmfGetHostGroupList(stmfGroupList **initiatorGroupList); int stmfGetHostGroupMembers(stmfGroupName *hostGroupName, stmfGroupProperties **groupProperties); @@ -371,6 +373,7 @@ stmfDevid *targetName); int stmfRemoveViewEntry(stmfGuid *lu, uint32_t viewEntryIndex); int stmfSetAluaState(boolean_t enabled, uint32_t node); +int stmfSetGlobalLuProp(uint16_t dType, uint32_t propType, const char *propVal); int stmfSetLuProp(luResource hdl, uint32_t propType, const char *propVal); int stmfSetPersistMethod(uint8_t persistType, boolean_t serviceSet); int stmfSetProviderData(char *providerName, nvlist_t *nvl, int providerType);
--- a/usr/src/lib/libstmf/common/mapfile-vers Thu Nov 19 15:28:11 2009 +1100 +++ b/usr/src/lib/libstmf/common/mapfile-vers Thu Nov 19 05:07:17 2009 -0800 @@ -53,6 +53,7 @@ stmfDevidFromWwn; stmfFreeLuResource; stmfFreeMemory; + stmfGetGlobalLuProp; stmfGetHostGroupList; stmfGetHostGroupMembers; stmfGetLuProp; @@ -85,6 +86,7 @@ stmfRemoveViewEntry; stmfSetAluaState; stmfGetAluaState; + stmfSetGlobalLuProp; stmfSetPersistMethod; stmfSetProviderData; stmfSetProviderDataProt;
--- a/usr/src/lib/libstmf/common/stmf.c Thu Nov 19 15:28:11 2009 +1100 +++ b/usr/src/lib/libstmf/common/stmf.c Thu Nov 19 05:07:17 2009 -0800 @@ -48,6 +48,7 @@ #include <sys/stmf_ioctl.h> #include <sys/stmf_sbd_ioctl.h> #include <sys/pppt_ioctl.h> +#include <macros.h> #define STMF_PATH "/devices/pseudo/stmf@0:admin" #define SBD_PATH "/devices/pseudo/stmf_sbd@0:admin" @@ -124,6 +125,7 @@ static int addGuidToDiskStore(stmfGuid *, char *); static int persistDiskGuid(stmfGuid *, char *, boolean_t); static int setDiskProp(luResourceImpl *, uint32_t, const char *); +static int getDiskGlobalProp(uint32_t prop, char *propVal, size_t *propLen); static int checkHexUpper(char *); static int strToShift(const char *); static int niceStrToNum(const char *, uint64_t *); @@ -138,6 +140,7 @@ static int groupMemberListIoctl(stmfGroupName *, stmfGroupProperties **, int); static int getProviderData(char *, nvlist_t **, int, uint64_t *); static int setDiskStandby(stmfGuid *luGuid); +static int setDiskGlobalProp(uint32_t, const char *); static int viewEntryCompare(const void *, const void *); static void deleteNonActiveLus(); @@ -2349,6 +2352,256 @@ return (ret); } +/* + * stmfGetGlobalLuProp + * + * Purpose: get a global property for a device type + * + */ +int +stmfGetGlobalLuProp(uint16_t dType, uint32_t prop, char *propVal, + size_t *propLen) +{ + int ret = STMF_STATUS_SUCCESS; + if (dType != STMF_DISK || propVal == NULL) { + return (STMF_ERROR_INVALID_ARG); + } + + ret = getDiskGlobalProp(prop, propVal, propLen); + + return (ret); +} + +/* + * getDiskGlobalProp + * + * Purpose: get global property from sbd driver + * + */ +static int +getDiskGlobalProp(uint32_t prop, char *propVal, size_t *propLen) +{ + int ret = STMF_STATUS_SUCCESS; + int fd; + sbd_global_props_t *sbdProps; + void *sbd_realloc; + int retryCnt = 0; + boolean_t retry; + int ioctlRet; + int savedErrno; + int sbdPropsSize = sizeof (*sbdProps) + MAX_SBD_PROPS; + stmf_iocdata_t sbdIoctl = {0}; + size_t reqLen; + + switch (prop) { + case STMF_LU_PROP_MGMT_URL: + break; + default: + return (STMF_ERROR_INVALID_PROP); + } + + /* + * Open control node for sbd + */ + if ((ret = openSbd(OPEN_SBD, &fd)) != STMF_STATUS_SUCCESS) + return (ret); + + sbdProps = calloc(1, sbdPropsSize); + if (sbdProps == NULL) { + (void) close(fd); + return (STMF_ERROR_NOMEM); + } + + do { + retry = B_FALSE; + sbdIoctl.stmf_version = STMF_VERSION_1; + sbdIoctl.stmf_obuf_size = sbdPropsSize; + sbdIoctl.stmf_obuf = (uint64_t)(unsigned long)sbdProps; + ioctlRet = ioctl(fd, SBD_IOCTL_GET_GLOBAL_LU, &sbdIoctl); + if (ioctlRet != 0) { + savedErrno = errno; + switch (savedErrno) { + case EBUSY: + ret = STMF_ERROR_BUSY; + break; + case EPERM: + case EACCES: + ret = STMF_ERROR_PERM; + break; + case ENOMEM: + if (sbdIoctl.stmf_error == + SBD_RET_INSUFFICIENT_BUF_SPACE && + retryCnt++ < 3) { + sbdPropsSize = + sizeof (*sbdProps) + + sbdProps-> + mlu_buf_size_needed; + + sbd_realloc = sbdProps; + sbdProps = realloc(sbdProps, + sbdPropsSize); + if (sbdProps == NULL) { + free(sbd_realloc); + ret = STMF_ERROR_NOMEM; + break; + } + retry = B_TRUE; + } else { + ret = STMF_ERROR_NOMEM; + } + break; + default: + syslog(LOG_DEBUG, + "getDiskGlobalProp:ioctl error(%d)" + "(%d)(%d)", ioctlRet, + sbdIoctl.stmf_error, savedErrno); + ret = STMF_STATUS_ERROR; + break; + } + + } + } while (retry); + + if (ret != STMF_STATUS_SUCCESS) { + goto done; + } + + switch (prop) { + case STMF_LU_PROP_MGMT_URL: + if (sbdProps->mlu_mgmt_url_valid == 0) { + ret = STMF_ERROR_NO_PROP; + goto done; + } + if ((reqLen = strlcpy(propVal, (char *)&( + sbdProps->mlu_buf[sbdProps->mlu_mgmt_url_off]), + *propLen)) >= *propLen) { + *propLen = reqLen + 1; + ret = STMF_ERROR_INVALID_ARG; + goto done; + } + break; + } + +done: + free(sbdProps); + (void) close(fd); + return (ret); +} + +/* + * stmfSetGlobalLuProp + * + * Purpose: set a global property for a device type + * + */ +int +stmfSetGlobalLuProp(uint16_t dType, uint32_t prop, const char *propVal) +{ + int ret = STMF_STATUS_SUCCESS; + if (dType != STMF_DISK || propVal == NULL) { + return (STMF_ERROR_INVALID_ARG); + } + + ret = setDiskGlobalProp(prop, propVal); + + return (ret); +} + +/* + * setDiskGlobalProp + * + * Purpose: set properties for resource of type disk + * + * resourceProp - valid resource identifier + * propVal - valid resource value + */ +static int +setDiskGlobalProp(uint32_t resourceProp, const char *propVal) +{ + int ret = STMF_STATUS_SUCCESS; + sbd_global_props_t *sbdGlobalProps = NULL; + int sbdGlobalPropsSize = 0; + int propLen; + int mluBufSize = 0; + int fd; + int savedErrno; + int ioctlRet; + stmf_iocdata_t sbdIoctl = {0}; + + switch (resourceProp) { + case STMF_LU_PROP_MGMT_URL: + break; + default: + return (STMF_ERROR_INVALID_PROP); + break; + } + + /* + * Open control node for sbd + */ + if ((ret = openSbd(OPEN_SBD, &fd)) != STMF_STATUS_SUCCESS) + return (ret); + + propLen = strlen(propVal); + mluBufSize += propLen + 1; + sbdGlobalPropsSize += sizeof (sbd_global_props_t) - 8 + + max(8, mluBufSize); + /* + * 8 is the size of the buffer set aside for + * concatenation of variable length fields + */ + sbdGlobalProps = (sbd_global_props_t *)calloc(1, sbdGlobalPropsSize); + if (sbdGlobalProps == NULL) { + (void) close(fd); + return (STMF_ERROR_NOMEM); + } + + sbdGlobalProps->mlu_struct_size = sbdGlobalPropsSize; + + switch (resourceProp) { + case STMF_LU_PROP_MGMT_URL: + sbdGlobalProps->mlu_mgmt_url_valid = 1; + bcopy(propVal, &(sbdGlobalProps->mlu_buf), + propLen + 1); + break; + default: + ret = STMF_ERROR_NO_PROP; + goto done; + } + + sbdIoctl.stmf_version = STMF_VERSION_1; + sbdIoctl.stmf_ibuf_size = sbdGlobalProps->mlu_struct_size; + sbdIoctl.stmf_ibuf = (uint64_t)(unsigned long)sbdGlobalProps; + + ioctlRet = ioctl(fd, SBD_IOCTL_SET_GLOBAL_LU, &sbdIoctl); + if (ioctlRet != 0) { + savedErrno = errno; + switch (savedErrno) { + case EBUSY: + ret = STMF_ERROR_BUSY; + break; + case EPERM: + case EACCES: + ret = STMF_ERROR_PERM; + break; + default: + diskError(sbdIoctl.stmf_error, &ret); + if (ret == STMF_STATUS_ERROR) { + syslog(LOG_DEBUG, + "modifyDiskLu:ioctl " + "error(%d) (%d) (%d)", ioctlRet, + sbdIoctl.stmf_error, savedErrno); + } + break; + } + } + +done: + free(sbdGlobalProps); + (void) close(fd); + return (ret); +} + /* * stmfSetLuProp
--- a/usr/src/uts/common/io/comstar/lu/stmf_sbd/sbd.c Thu Nov 19 15:28:11 2009 +1100 +++ b/usr/src/uts/common/io/comstar/lu/stmf_sbd/sbd.c Thu Nov 19 05:07:17 2009 -0800 @@ -77,6 +77,10 @@ int sbd_import_active_lu(sbd_import_lu_t *ilu, sbd_lu_t *sl, uint32_t *err_ret); int sbd_delete_lu(sbd_delete_lu_t *dlu, int struct_sz, uint32_t *err_ret); int sbd_modify_lu(sbd_modify_lu_t *mlu, int struct_sz, uint32_t *err_ret); +int sbd_set_global_props(sbd_global_props_t *mlu, int struct_sz, + uint32_t *err_ret); +int sbd_get_global_props(sbd_global_props_t *oslp, uint32_t oslp_sz, + uint32_t *err_ret); int sbd_get_lu_props(sbd_lu_props_t *islp, uint32_t islp_sz, sbd_lu_props_t *oslp, uint32_t oslp_sz, uint32_t *err_ret); char *sbd_get_zvol_name(sbd_lu_t *sl); @@ -98,9 +102,15 @@ static kmutex_t sbd_lock; static dev_info_t *sbd_dip; static uint32_t sbd_lu_count = 0; + +/* Global property settings for the logical unit */ char sbd_vendor_id[] = "SUN "; char sbd_product_id[] = "COMSTAR "; char sbd_revision[] = "1.0 "; +char *sbd_mgmt_url = NULL; +uint16_t sbd_mgmt_url_alloc_size = 0; +krwlock_t sbd_global_prop_lock; + static char sbd_name[] = "sbd"; static struct cb_ops sbd_cb_ops = { @@ -176,6 +186,7 @@ return (EINVAL); } mutex_init(&sbd_lock, NULL, MUTEX_DRIVER, NULL); + rw_init(&sbd_global_prop_lock, NULL, RW_DRIVER, NULL); return (0); } @@ -222,6 +233,7 @@ } stmf_free(sbd_lp); mutex_destroy(&sbd_lock); + rw_destroy(&sbd_global_prop_lock); ldi_ident_release(sbd_zfs_ident); return (0); } @@ -384,6 +396,30 @@ ret = sbd_modify_lu((sbd_modify_lu_t *)ibuf, iocd->stmf_ibuf_size, &iocd->stmf_error); break; + case SBD_IOCTL_SET_GLOBAL_LU: + if (iocd->stmf_ibuf_size < (sizeof (sbd_global_props_t) - 8)) { + ret = EFAULT; + break; + } + if (iocd->stmf_obuf_size) { + ret = EINVAL; + break; + } + ret = sbd_set_global_props((sbd_global_props_t *)ibuf, + iocd->stmf_ibuf_size, &iocd->stmf_error); + break; + case SBD_IOCTL_GET_GLOBAL_LU: + if (iocd->stmf_ibuf_size) { + ret = EINVAL; + break; + } + if (iocd->stmf_obuf_size < sizeof (sbd_global_props_t)) { + ret = EINVAL; + break; + } + ret = sbd_get_global_props((sbd_global_props_t *)obuf, + iocd->stmf_obuf_size, &iocd->stmf_error); + break; case SBD_IOCTL_GET_LU_PROPS: if (iocd->stmf_ibuf_size < (sizeof (sbd_lu_props_t) - 8)) { ret = EFAULT; @@ -2743,6 +2779,74 @@ return (ret); } +int +sbd_set_global_props(sbd_global_props_t *mlu, int struct_sz, + uint32_t *err_ret) +{ + sbd_lu_t *sl = NULL; + int ret = 0; + sbd_it_data_t *it; + uint32_t sz; + + sz = struct_sz - sizeof (*mlu) + 8 + 1; + + /* if there is data in the buf, null terminate it */ + if (struct_sz > sizeof (*mlu)) { + mlu->mlu_buf[struct_sz - sizeof (*mlu) + 8 - 1] = 0; + } + + *err_ret = 0; + + /* Lets validate offsets */ + if (((mlu->mlu_mgmt_url_valid) && + (mlu->mlu_mgmt_url_off >= sz))) { + return (EINVAL); + } + + if (mlu->mlu_mgmt_url_valid) { + uint16_t url_sz; + + url_sz = strlen((char *)mlu->mlu_buf + mlu->mlu_mgmt_url_off); + if (url_sz > 0) + url_sz++; + + rw_enter(&sbd_global_prop_lock, RW_WRITER); + if (sbd_mgmt_url_alloc_size > 0 && + (url_sz == 0 || sbd_mgmt_url_alloc_size < url_sz)) { + kmem_free(sbd_mgmt_url, sbd_mgmt_url_alloc_size); + sbd_mgmt_url = NULL; + sbd_mgmt_url_alloc_size = 0; + } + if (url_sz > 0) { + if (sbd_mgmt_url_alloc_size == 0) { + sbd_mgmt_url = kmem_alloc(url_sz, KM_SLEEP); + sbd_mgmt_url_alloc_size = url_sz; + } + (void) strcpy(sbd_mgmt_url, (char *)mlu->mlu_buf + + mlu->mlu_mgmt_url_off); + } + /* + * check each lu to determine whether a UA is needed. + */ + mutex_enter(&sbd_lock); + for (sl = sbd_lu_list; sl; sl = sl->sl_next) { + if (sl->sl_mgmt_url) { + continue; + } + mutex_enter(&sl->sl_lock); + for (it = sl->sl_it_list; it != NULL; + it = it->sbd_it_next) { + it->sbd_it_ua_conditions |= + SBD_UA_MODE_PARAMETERS_CHANGED; + } + mutex_exit(&sl->sl_lock); + } + mutex_exit(&sbd_lock); + rw_exit(&sbd_global_prop_lock); + } + return (ret); +} + /* ARGSUSED */ int sbd_delete_locked_lu(sbd_lu_t *sl, uint32_t *err_ret, @@ -2946,6 +3050,38 @@ } int +sbd_get_global_props(sbd_global_props_t *oslp, uint32_t oslp_sz, + uint32_t *err_ret) +{ + uint32_t sz = 0; + uint16_t off; + + rw_enter(&sbd_global_prop_lock, RW_READER); + if (sbd_mgmt_url) { + sz += strlen(sbd_mgmt_url) + 1; + } + bzero(oslp, sizeof (*oslp) - 8); + oslp->mlu_buf_size_needed = sz; + + if (sz > (oslp_sz - sizeof (*oslp) + 8)) { + *err_ret = SBD_RET_INSUFFICIENT_BUF_SPACE; + rw_exit(&sbd_global_prop_lock); + return (ENOMEM); + } + + off = 0; + if (sbd_mgmt_url) { + oslp->mlu_mgmt_url_valid = 1; + oslp->mlu_mgmt_url_off = off; + (void) strcpy((char *)&oslp->mlu_buf[off], sbd_mgmt_url); + off += strlen(sbd_mgmt_url) + 1; + } + + rw_exit(&sbd_global_prop_lock); + return (0); +} + +int sbd_get_lu_props(sbd_lu_props_t *islp, uint32_t islp_sz, sbd_lu_props_t *oslp, uint32_t oslp_sz, uint32_t *err_ret) { @@ -2984,8 +3120,11 @@ sz += strlen(sl->sl_alias) + 1; } + rw_enter(&sbd_global_prop_lock, RW_READER); if (sl->sl_mgmt_url) { sz += strlen(sl->sl_mgmt_url) + 1; + } else if (sbd_mgmt_url) { + sz += strlen(sbd_mgmt_url) + 1; } bzero(oslp, sizeof (*oslp) - 8); oslp->slp_buf_size_needed = sz; @@ -2993,6 +3132,7 @@ if (sz > (oslp_sz - sizeof (*oslp) + 8)) { sl->sl_trans_op = SL_OP_NONE; *err_ret = SBD_RET_INSUFFICIENT_BUF_SPACE; + rw_exit(&sbd_global_prop_lock); return (ENOMEM); } @@ -3028,6 +3168,11 @@ oslp->slp_mgmt_url_off = off; (void) strcpy((char *)&oslp->slp_buf[off], sl->sl_mgmt_url); off += strlen(sl->sl_mgmt_url) + 1; + } else if (sbd_mgmt_url) { + oslp->slp_mgmt_url_valid = 1; + oslp->slp_mgmt_url_off = off; + (void) strcpy((char *)&oslp->slp_buf[off], sbd_mgmt_url); + off += strlen(sbd_mgmt_url) + 1; } if (sl->sl_serial_no_size) { oslp->slp_serial_off = off; @@ -3072,6 +3217,7 @@ sl->sl_trans_op = SL_OP_NONE; + rw_exit(&sbd_global_prop_lock); return (0); }
--- a/usr/src/uts/common/io/comstar/lu/stmf_sbd/sbd_scsi.c Thu Nov 19 15:28:11 2009 +1100 +++ b/usr/src/uts/common/io/comstar/lu/stmf_sbd/sbd_scsi.c Thu Nov 19 05:07:17 2009 -0800 @@ -1138,6 +1138,7 @@ uint16_t cmd_size; uint32_t xfer_size = 4; uint32_t mgmt_url_size = 0; + char *mgmt_url = NULL; byte0 = DTYPE_DIRECT; @@ -1168,10 +1169,6 @@ return; } - if (sl->sl_mgmt_url) { - mgmt_url_size = strlen(sl->sl_mgmt_url); - } - /* * Standard inquiry */ @@ -1270,6 +1267,15 @@ return; } + rw_enter(&sbd_global_prop_lock, RW_READER); + if (sl->sl_mgmt_url) { + mgmt_url_size = strlen(sl->sl_mgmt_url); + mgmt_url = sl->sl_mgmt_url; + } else if (sbd_mgmt_url) { + mgmt_url_size = strlen(sbd_mgmt_url); + mgmt_url = sbd_mgmt_url; + } + /* * EVPD handling */ @@ -1325,8 +1331,7 @@ if (mgmt_url_size == 0) { stmf_scsilib_send_status(task, STATUS_CHECK, STMF_SAA_INVALID_FIELD_IN_CDB); - kmem_free(p, bsize); - return; + goto err_done; } { uint16_t idx, newidx, sz, url_size; @@ -1336,7 +1341,7 @@ p[1] = 0x85; idx = 4; - url = sl->sl_mgmt_url; + url = mgmt_url; url_size = sbd_parse_mgmt_url(&url); /* Creating Network Service Descriptors */ while (url_size != 0) { @@ -1390,13 +1395,14 @@ default: stmf_scsilib_send_status(task, STATUS_CHECK, STMF_SAA_INVALID_FIELD_IN_CDB); - kmem_free(p, bsize); - return; + goto err_done; } sbd_handle_short_read_transfers(task, initial_dbuf, p, cmd_size, min(cmd_size, xfer_size)); +err_done: kmem_free(p, bsize); + rw_exit(&sbd_global_prop_lock); } stmf_status_t
--- a/usr/src/uts/common/io/comstar/lu/stmf_sbd/stmf_sbd.h Thu Nov 19 15:28:11 2009 +1100 +++ b/usr/src/uts/common/io/comstar/lu/stmf_sbd/stmf_sbd.h Thu Nov 19 05:07:17 2009 -0800 @@ -34,6 +34,10 @@ extern char sbd_vendor_id[]; extern char sbd_product_id[]; extern char sbd_revision[]; +extern char *sbd_mgmt_url; +extern uint16_t sbd_mgmt_url_alloc_size; +extern krwlock_t sbd_global_prop_lock; + /* * Error codes */
--- a/usr/src/uts/common/io/comstar/stmf/stmf.c Thu Nov 19 15:28:11 2009 +1100 +++ b/usr/src/uts/common/io/comstar/stmf/stmf.c Thu Nov 19 05:07:17 2009 -0800 @@ -5481,7 +5481,9 @@ case TM_LUN_RESET: stmf_handle_lun_reset(task); /* issue the reset to the proxy node as well */ - (void) stmf_proxy_scsi_cmd(task, NULL); + if (stmf_state.stmf_alua_state == 1) { + (void) stmf_proxy_scsi_cmd(task, NULL); + } return; case TM_TARGET_RESET: case TM_TARGET_COLD_RESET:
--- a/usr/src/uts/common/sys/stmf_sbd_ioctl.h Thu Nov 19 15:28:11 2009 +1100 +++ b/usr/src/uts/common/sys/stmf_sbd_ioctl.h Thu Nov 19 05:07:17 2009 -0800 @@ -74,6 +74,8 @@ #define SBD_IOCTL_GET_LU_PROPS SBD_IOCTL_DEF(5) #define SBD_IOCTL_GET_LU_LIST SBD_IOCTL_DEF(6) #define SBD_IOCTL_SET_LU_STANDBY SBD_IOCTL_DEF(7) +#define SBD_IOCTL_SET_GLOBAL_LU SBD_IOCTL_DEF(8) +#define SBD_IOCTL_GET_GLOBAL_LU SBD_IOCTL_DEF(9) typedef struct sbd_create_and_reg_lu { uint32_t slu_struct_size; @@ -110,6 +112,29 @@ char slu_buf[8]; /* likely more than 8 */ } sbd_create_and_reg_lu_t; +typedef struct sbd_global_props { + uint32_t mlu_struct_size; + uint32_t mlu_vid_valid:1, + mlu_pid_valid:1, + mlu_rev_valid:1, + mlu_serial_valid:1, + mlu_mgmt_url_valid:1, + mlu_company_id_valid:1, + mlu_host_id_valid:1; + uint16_t mlu_serial_off; + uint8_t mlu_serial_size; + uint8_t mlu_rsvd1; + uint32_t mlu_company_id; + uint16_t mlu_mgmt_url_off; + uint16_t rsvd1; + uint32_t mlu_host_id; + uint32_t mlu_buf_size_needed; + char mlu_rev[4]; + char mlu_vid[8]; + char mlu_pid[16]; + char mlu_buf[8]; /* likely more than 8 */ +} sbd_global_props_t; + typedef struct sbd_set_lu_standby { uint8_t stlu_guid[16]; } sbd_set_lu_standby_t;