fcinfo-list.c revision 63c17d01856124d99676ad972bf973d4a005a877
/*
* CDDL HEADER START
*
* The contents of this file are subject to the terms of the
* Common Development and Distribution License (the "License").
* You may not use this file except in compliance with the License.
*
* You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
* See the License for the specific language governing permissions
* and limitations under the License.
*
* When distributing Covered Code, include this CDDL HEADER in each
* file and include the License file at usr/src/OPENSOLARIS.LICENSE.
* If applicable, add the following below this CDDL HEADER, with the
* fields enclosed by brackets "[]" replaced with your own identifying
* information: Portions Copyright [yyyy] [name of copyright owner]
*
* CDDL HEADER END
*/
/*
* Copyright 2008 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
#include "fcinfo.h"
#include <libintl.h>
struct lun {
};
typedef enum {
typedef struct rep_luns_rsp {
/*
* This function retrieve the adapater attributes, port attributes, and
* portIndex for the given handle and hba port WWN.
*
* Arguments:
* handle an HBA_HANDLE to a adapter
* hbaPortWWN WWN of the port on the adapter to which to retrieve
* HBA_PORTATTRIBUTES from
* attrs pointer to a HBA_ADAPTERATTRIBUTES structure. Upon
* successful completion, this structure will be filled in
* port pointer to a HBA_PORTATTRIBUTES structure. Upon successful
* completion, this structure will be fill in
* portIndex the Index count of the port on the adapter that is
* associated with the WWN.
*
* Returns
* 0 successfully retrieve all information
* >0 otherwise
*/
static int
{
int portCtr;
int times;
/* argument checking */
"retreiveAttrs\n"));
return (1);
}
/* retrieve Adapter attributes */
times = 0;
while ((status == HBA_STATUS_ERROR_TRY_AGAIN ||
status == HBA_STATUS_ERROR_BUSY) &&
times++ < HBA_MAX_RETRIES) {
(void) sleep(1);
if (status == HBA_STATUS_OK) {
break;
}
}
if (status != HBA_STATUS_OK) {
"attributes handle(%d) Reason: "), handle);
return (1);
}
/*
* find the corresponding port on the adapter and retrieve
* port attributes as well as the port index
*/
gettext("Error: Failed to get port (%d) "
"attributes reason: "), portCtr);
return (1);
}
break;
}
}
/*
* not able to find corresponding port WWN
* returning an error
*/
*portIndex = 0;
return (1);
}
return (0);
}
/*
* This function retrieves target mapping information for the HBA port WWN.
* This function will allocate space for the mapping structure which the caller
* must free when they are finished
*
* Arguments:
* handle - a handle to a HBA that we will be processing
* hbaPortWWN - the port WWN for the HBA port to retrieve the mappings for
* mapping - a pointer to a pointer for the target mapping structure
* Upon successful completion of this function, *mapping will contain
* the target mapping information
*
* returns:
* 0 if successful
* 1 otherwise
*/
static int
{
int count;
/* argument sanity checking */
return (1);
}
gettext("Internal Error: Unable to calloc map"));
return (1);
}
if (status == HBA_STATUS_ERROR_MORE_DATA) {
sizeof (HBA_FCPTARGETMAPPINGV2))) == NULL) {
return (1);
}
}
if (status != HBA_STATUS_OK) {
gettext("Error: Unable to get Target Mapping\n"));
return (1);
}
return (0);
}
/*
* This function handles the remoteport object. It will issue a report lun
* to determine whether it is a scsi-target and then print the information.
*
* Arguments:
* handle - a handle to a HBA that we will be processing
* portWWN - the port WWN for the HBA port we will be issuing the SCSI
* ReportLUNS through
* remotePortWWN - the port WWN we will be issuing the report lun call to
* discPort - PORTATTRIBUTES structure for the remotePortWWN
*/
static void
{
int scsiTargetType;
struct scsi_extended_sense sense;
/* argument checking */
return;
}
/* going to issue a report lun to check if this is a scsi-target */
if (status == HBA_STATUS_OK) {
} else if (status == HBA_STATUS_ERROR_NOT_A_TARGET) {
} else {
}
}
/*
* This function will issue the RLS and print out the port statistics for
* the given destWWN
*
* Arguments
* handle - a handle to a HBA that we will be processing
* hbaPortWWN - the hba port WWN through which the RLS will be sent
* destWWN - the remote port to which the RLS will be sent
*/
static void
{
rls_payload_size = sizeof (rls_payload);
if (status != HBA_STATUS_OK) {
} else {
}
}
int
{
int index;
int times = 0;
while (status == HBA_STATUS_ERROR_TRY_AGAIN ||
status == HBA_STATUS_ERROR_BUSY) {
(void) sleep(1);
if (times++ > HBA_MAX_RETRIES) {
break;
}
}
if (status == HBA_STATUS_ERROR_NOT_SUPPORTED) {
return (0);
}
if (status != HBA_STATUS_OK) {
gettext("Error: Failed to get port (%d) "
"npiv attributes reason: "), portindex);
return (1);
}
if (portattrs.MaxNumberOfNPIVPorts) {
} else {
return (0);
}
int times = 0;
while (status == HBA_STATUS_ERROR_TRY_AGAIN ||
status == HBA_STATUS_ERROR_BUSY) {
(void) sleep(1);
if (times++ > HBA_MAX_RETRIES) {
break;
}
}
if (status != HBA_STATUS_OK) {
gettext("Error: Failed to get npiv port (%d) "
"attributes reason: "), index);
return (1);
} else {
}
}
return (0);
}
/*
* This function will process hba port, remote port and scsi-target information
* for the given handle.
*
* Arguments:
* handle - a handle to a HBA that we will be processing
* resourceType - resourceType flag
* possible values include: HBA_PORT, REMOTE_PORT
* flags - represents options passed in by the user
*
* Return Value:
* 0 sucessfully processed handle
* 1 error has occured
*/
static int
{
int discPortCount;
if (resourceType == HBA_PORT) {
}
return (0);
}
/*
* process each of the remote targets from this hba port
*/
for (discPortCount = 0;
discPortCount++) {
if (status != HBA_STATUS_OK) {
gettext("Failed to get discovered port (%d)"
" attributes reason :"), discPortCount);
continue;
}
if (resourceType == REMOTE_PORT) {
&discPort);
}
}
}
}
return (0);
}
/*
* This function will process remote port information for the given handle.
*
* Arguments:
* handle - a handle to a HBA that we will be processing
* portWWN - the port WWN for the HBA port we will be issuing the SCSI
* ReportLUNS through
* wwnCount - the number of wwns in wwn_argv
* wwn_argv - argument vector of WWNs
*/
static void
{
int remote_wwn_counter;
for (remote_wwn_counter = 0;
remote_wwn_counter++) {
int times = 0;
sizeof (remotePortWWN));
&discPort);
while (status == HBA_STATUS_ERROR_TRY_AGAIN ||
status == HBA_STATUS_ERROR_BUSY) {
(void) sleep(1);
if (times++ > HBA_MAX_RETRIES) {
break;
}
}
if (status != HBA_STATUS_OK) {
"failed: reason: "));
continue;
}
}
}
}
}
/*
* This function handles printing Scsi target information for remote ports
*
* Arguments:
* handle - a handle to a HBA that we will be processing
* hbaPortWWN - the port WWN for the HBA port through which the SCSI call
* is being sent
* scsiTargetWWN - target port WWN of the remote target the SCSI call is
* being sent to
* map - a pointer to the target mapping structure for the given HBA port
*/
static void
{
struct scsi_inquiry inq;
struct scsi_extended_sense sense;
senseSize = sizeof (struct scsi_extended_sense);
/*
* if HBA_STATUS_ERROR_NOT_A_TARGET is return, we can assume this is
* a remote HBA and move on
*/
if (status == HBA_STATUS_ERROR_NOT_A_TARGET) {
return;
} else if (status != HBA_STATUS_OK) {
"HBA_ScsiReportLUNsV2 failed. reason "));
return;
}
/*
* now issue standard inquiry to get Vendor
* and product information
*/
responseSize = sizeof (struct scsi_inquiry);
senseSize = sizeof (struct scsi_extended_sense);
0, /* EVPD */
0,
&inq, &responseSize,
if (status != HBA_STATUS_OK) {
}
sizeof (scsiTargetWWN.wwn))
== 0) &&
break;
}
}
lun_string[1];
}
} else {
/* Not able to get any target mapping information */
lun_string[1];
}
}
}
/*
* function to handle the list remoteport command
*
* Arguments:
* wwnCount - the number of wwns in wwn_argv
* if wwnCount == 0, then print information on all
* remote ports. wwn_argv will not be used in this case
* if wwnCount > 0, then print information for the WWNs
* given in wwn_argv
* wwn_argv - argument vector of WWNs
* options - any options specified by the caller
*
* returns:
* 0 if successful
* 1 otherwise
*/
int
{
int processHBA_flags = 0, portCount = 0;
int mode;
/* grab the hba port wwn from the -p option */
&hbaPortWWN);
} else {
return (1);
}
}
/*
* -h option was not specified, this should not happen either.
* cmdparse should catch this problem, but checking anyways
*/
if (hbaPortWWN == 0) {
gettext("Error: -p option was not specified.\n"));
return (1);
}
gettext("Failed to load FC-HBA common library\n"));
return (1);
}
!= HBA_STATUS_OK) {
if (status != HBA_STATUS_OK) {
gettext("Error: Failed to open adapter port. Reason "));
return (1);
} else {
if ((processHBA_flags & PRINT_SCSI_TARGET) ==
"Error: Unsupported option for target mode: %c.\n"),
's');
return (1);
}
mode = TARGET_MODE;
}
} else {
}
}
if (wwnCount == 0) {
/* get adapater attributes for the given handle */
&portCount) != 0) {
}
return (1);
}
} else {
}
}
return (0);
}
/*
* process the hbaport object
*
* Arguments:
* wwnCount - count of the number of WWNs in wwn_argv
* if wwnCount > 0, then we will only print information for
* the hba ports listed in wwn_argv
* if wwnCount == 0, then we will print information on all hba ports
* wwn_argv - argument array of hba port WWNs
* options - any options specified by the caller
*
* returns:
* 0 if successful
* 1 otherwise
*/
int
{
char adapterName[256];
int processHBA_flags = 0;
int mode;
/* process each of the options */
}
}
/*
* specified.
*/
if (((processHBA_flags & PRINT_INITIATOR) == 0) &&
((processHBA_flags & PRINT_TARGET) == 0)) {
}
gettext("Failed to load FC-HBA common library\n"));
return (1);
}
if (wwnCount > 0) {
/* list only ports given in wwn_argv */
for (port_wwn_counter = 0;
port_wwn_counter++) {
/* first check to see if it is an initiator port. */
if ((processHBA_flags & PRINT_INITIATOR) ==
int times = 0;
while (status == HBA_STATUS_ERROR_TRY_AGAIN ||
status == HBA_STATUS_ERROR_BUSY) {
(void) sleep(1);
if (times++ > HBA_MAX_RETRIES) {
break;
}
}
if (status != HBA_STATUS_OK) {
/* now see if it is a target mode FC port */
if ((processHBA_flags & PRINT_TARGET) ==
PRINT_TARGET) {
status =
if (status != HBA_STATUS_OK) {
"Error: HBA port %s: not found\n"),
err_cnt++;
continue;
} else {
/* set the port mode. */
mode = TARGET_MODE;
}
} else {
"Error: HBA port %s: not found\n"),
err_cnt++;
continue;
}
} else {
/* set the port mode. */
}
/* try target mode discovery if print target is set. */
} else if ((processHBA_flags & PRINT_TARGET) ==
PRINT_TARGET) {
status =
if (status != HBA_STATUS_OK) {
"Error: HBA port %s: not found\n"),
err_cnt++;
continue;
} else {
/* set the port mode. */
mode = TARGET_MODE;
}
} else {
/* should not get here. */
"Error: HBA port %s: not found\n"),
err_cnt++;
continue;
}
&portIndex) != 0) {
continue;
}
!= 0) {
err_cnt++;
}
}
} else {
/*
* if PRINT_INITIATOR is specified, get the list of initiator
* mod port.
*/
if ((numAdapters == 0) &&
((processHBA_flags & ~PRINT_INITIATOR) == 0)) {
}
for (i = 0; i < numAdapters; i++) {
int times = 0;
if (status != HBA_STATUS_OK) {
"failed to get adapter %d. Reason: "), i);
continue;
}
"Failed to open adapter %s.\n"),
continue;
}
/* get adapater attributes for the given handle */
status =
&attrs);
while ((status == HBA_STATUS_ERROR_TRY_AGAIN ||
status == HBA_STATUS_ERROR_BUSY) &&
times++ < HBA_MAX_RETRIES) {
(void) sleep(1);
status =
&attrs);
if (status == HBA_STATUS_OK) {
break;
}
}
if (status != HBA_STATUS_OK) {
gettext("Failed to get adapter attributes "
"handle(%d) Reason: "), handle);
continue;
}
/* process each port on the given adatpter */
for (portIndex = 0;
portIndex++) {
if ((status = HBA_GetAdapterPortAttributes(
!= HBA_STATUS_OK) {
/*
* not able to get port attributes.
* print out error * message and move
* on to the next port
*/
gettext("Error: Failed to get port "
"(%d) attributes reason: "),
continue;
}
!= 0) {
err_cnt++;
}
}
}
}
/*
* Get the info on the target mode FC port if PRINT_TARGET
* is specified.
*/
if (numTgtAdapters == 0 && numAdapters == 0) {
gettext("No Adapters Found.\n"));
}
for (i = 0; i < numTgtAdapters; i++) {
if (status != HBA_STATUS_OK) {
"failed to get adapter %d. Reason: "), i);
continue;
}
== 0) {
"Failed to open adapter %s.\n"), adapterName);
continue;
}
/* get adapater attributes for the given handle */
!= HBA_STATUS_OK) {
gettext("Failed to get target mode adapter"
"attributes handle(%d) Reason: "),
handle);
continue;
}
/* process each port on the given adatpter */
for (portIndex = 0;
portIndex++) {
if ((status = HBA_GetAdapterPortAttributes(
!= HBA_STATUS_OK) {
/*
* not able to get port attributes.
* print out error * message and move
* on to the next port
*/
gettext("Error: Failed to get port "
"(%d) attributes reason: "),
continue;
}
}
}
}
}
/*
* print additional error msg for partial failure when more than
* one wwn is specified.
*/
if (err_cnt != 0) {
if (wwnCount > 1) {
"Error: All specified HBA ports are not found\n"));
} else {
"Error: Some of specified HBA ports are not found\n"));
}
}
return (1);
}
return (0);
}
/*
* Search the existing device list
*
* Take one of two actions:
*
* Add an entry if an entry doesn't exist
* Add WWN data to it if an entry does exist
*
* Arguments:
* devList - OS device path list
* map - target mapping data
* index - index into target mapping data
* initiatorPortWWN - HBA port WWN
* verbose - boolean indicating whether to get additional data
*
* returns:
* none
*/
static void
{
struct scsi_inquiry inq;
struct scsi_extended_sense sense;
discoveredDevList->OSDeviceName) == 0) {
/*
* if only device names are requested,
* no reason to go any further
*/
return;
}
break;
}
}
if (foundDevice == B_TRUE) {
/* add initiator Port WWN if it doesn't exist */
(void *)&initiatorPortWWN,
sizeof (HBA_WWN)) == 0) {
break;
}
}
responseSize = sizeof (struct scsi_inquiry);
senseSize = sizeof (struct scsi_extended_sense);
0, /* CDB Byte 1 */
0, /* CDB Byte 2 */
&inq, &responseSize,
if (status == HBA_STATUS_OK) {
sizeof (discoveredDevList->VID));
sizeof (discoveredDevList->PID));
}
}
perror("Out of memory");
exit(1);
}
/* insert at head */
(void *)&initiatorPortWWN,
/* add Target Port */
sizeof (tgtPortWWNList));
perror("Out of memory");
exit(1);
}
/* Set LUN data */
} else { /* add it to existing */
sizeof (tgtPortWWNList));
perror("Out of memory");
exit(1);
}
/* insert at head */
/* Set LUN data */
}
} else { /* add new entry */
sizeof (discoveredDevice));
perror("Out of memory");
exit(1);
}
/* Copy device name */
/*
* if only device names are requested,
* no reason to go any further
*/
return;
}
/*
* copy WWN data
*/
sizeof (portWWNList));
perror("Out of memory");
exit(1);
}
perror("Out of memory");
exit(1);
}
/* Set LUN data */
responseSize = sizeof (struct scsi_inquiry);
senseSize = sizeof (struct scsi_extended_sense);
0, /* CDB Byte 1 */
0, /* CDB Byte 2 */
&inq, &responseSize,
if (status != HBA_STATUS_OK) {
/* initialize inq status */
} else {
/* initialize inq status */
}
}
}
/*
* process the logical-unit object
*
* Arguments:
* luCount - count of the number of device paths in paths_argv
* if pathCount > 0, then we will only print information for
* the device paths listed in paths_argv
* if pathCount == 0, then we will print information on all device
* paths
* luArgv - argument array of device paths
* options - any options specified by the caller
*
* returns:
* 0 if successful
* > 0 otherwise
*/
int
{
char adapterName[256];
int portIndex = 0;
int ret = 0;
/* process each of the options */
}
}
gettext("Failed to load FC-HBA common library\n"));
return (1);
}
/*
* Retrieve all device paths. We'll need to traverse the list
* until we find the input paths or all paths if none were given. We
* cannot print as we go since there can be duplicate paths returned
*/
if (numAdapters == 0) {
return (0);
}
for (i = 0; i < numAdapters; i++) {
int times;
if (status != HBA_STATUS_OK) {
"Failed to get adapter %d. Reason: "), i);
ret++;
continue;
}
ret++;
continue;
}
/* get adapter attributes for the given handle */
times = 0;
while ((status == HBA_STATUS_ERROR_TRY_AGAIN ||
status == HBA_STATUS_ERROR_BUSY) &&
times++ < HBA_MAX_RETRIES) {
(void) sleep(1);
if (status == HBA_STATUS_OK) {
break;
}
}
if (status != HBA_STATUS_OK) {
gettext("Failed to get adapter attributes "
"handle(%d) Reason: "), handle);
ret++;
continue;
}
/* process each port on adapter */
portIndex++) {
/*
* not able to get port attributes.
* print out error message and move
* on to the next port
*/
"(%d) attributes reason: "),
ret++;
continue;
}
/* get OS Device Paths */
count++) {
}
}
}
}
if (luCount == 0) {
/* list all paths */
}
} else {
/*
* list any paths not found first
* this gives the user cleaner output
*/
devListWalk != NULL;
}
}
ret++;
}
}
/* list all paths requested in order requested */
verbose);
}
}
}
}
return (ret);
}