Sign Up
Log In
Log In
or
Sign Up
Places
All Projects
Status Monitor
Collapse sidebar
openSUSE:Leap:42.1:Staging:C
fcoe-utils
0011-fcoeadm-Use-internal-sysfs-lib-to-display-...
Overview
Repositories
Revisions
Requests
Users
Attributes
Meta
File 0011-fcoeadm-Use-internal-sysfs-lib-to-display-target-and.patch of Package fcoe-utils
From 5943c59ae58a4b4c078c55453a8b3cef8b30d6a2 Mon Sep 17 00:00:00 2001 Message-Id: <5943c59ae58a4b4c078c55453a8b3cef8b30d6a2.1439372158.git.jthumshirn@suse.de> In-Reply-To: <cover.1439372158.git.jthumshirn@suse.de> References: <cover.1439372158.git.jthumshirn@suse.de> From: Johannes Thumshirn <jthumshirn@suse.de> Date: Mon, 3 Aug 2015 16:08:08 +0200 Subject: [PATCH 3/9] fcoeadm: Use internal sysfs lib to display target and LUN info Use internal sysfs lib to display target and LUN info using fcoeadm -t or fcoeadm -l. Signed-off-by: Johannes Thumshirn <jthumshirn@suse.de> --- fcoeadm_display.c | 1114 +++++++++++++++++---------------------------------- fcoeadm_display.h | 4 +- include/sysfs_hba.h | 6 + lib/sysfs_hba.c | 73 +++- 4 files changed, 450 insertions(+), 747 deletions(-) diff --git a/fcoeadm_display.c b/fcoeadm_display.c index c42cba6..80b2eb9 100644 --- a/fcoeadm_display.c +++ b/fcoeadm_display.c @@ -17,6 +17,8 @@ * Maintained at www.Open-FCoE.org */ +#define _GNU_SOURCE + #include <sys/param.h> #include <sys/ioctl.h> #include <linux/types.h> @@ -25,6 +27,7 @@ #include <stdio.h> #include <stdlib.h> #include <stdarg.h> +#include <stdbool.h> #include <time.h> #include <malloc.h> #include <pthread.h> @@ -34,6 +37,7 @@ #include <net/if.h> #include <unistd.h> #include <inttypes.h> +#include <dirent.h> #include "net_types.h" #include "fc_types.h" @@ -90,6 +94,14 @@ struct hba_name_table_list { struct hba_name_table hba_table[1]; }; +/* + * Options for displaying target/LUN info. + */ +struct target_info_arguments { + char *ifname; + enum disp_style style; +}; + struct sa_nameval port_states[] = { { "Not Present", HBA_PORTSTATE_UNKNOWN }, { "Online", HBA_PORTSTATE_ONLINE }, @@ -104,6 +116,15 @@ struct sa_nameval port_states[] = { { NULL, 0 } }; +#define HBA_PORTSPEED_4GBIT 0x0008 /* 4 GBit/sec */ +#define HBA_PORTSPEED_8GBIT 0x0010 /* 8 GBit/sec */ +#define HBA_PORTSPEED_16GBIT 0x0020 /* 16 GBit/sec */ +#define HBA_PORTSPEED_32GBIT 0x0040 /* 32 GBit/sec */ +#define HBA_PORTSPEED_20GBIT 0x0080 /* 20 GBit/sec */ +#define HBA_PORTSPEED_40GBIT 0x0100 /* 40 GBit/sec */ +#define HBA_PORTSPEED_NOT_NEGOTIATED (1 << 15) /* Speed not established */ + + /* * table of /sys port speed strings to HBA-API values. */ @@ -122,37 +143,14 @@ struct sa_nameval port_speeds[] = { { NULL, 0 } }; -static void -sa_dump_wwn(void *Data, int Length, int Break) -{ - unsigned char *pc = (unsigned char *)Data; - int i; - - for (i = 1; i <= Length; i++) { - printf("%02X", (int)*pc++); - if ((Break != 0) && (!(i % Break))) - printf(" "); - } -} - -static int is_fcp_target(HBA_PORTATTRIBUTES *rp_info) +static int is_fcp_target(struct port_attributes *rp_info) { - char buf[MAX_STR_LEN]; - - if (sa_sys_read_line(rp_info->OSDeviceName, "roles", buf, sizeof(buf))) - return -EINVAL; - - if (!strncmp(buf, FCP_TARG_STR, strlen(FCP_TARG_STR))) + if (!strncmp(rp_info->roles, FCP_TARG_STR, strlen(FCP_TARG_STR))) return 0; return -EINVAL; } -static void show_wwn(unsigned char *pWwn) -{ - sa_dump_wwn(pWwn, 8, 0); -} - static void show_hba_info(struct hba_info *hba_info) { printf(" Description: %s\n", hba_info->model_description); @@ -191,7 +189,7 @@ static void show_port_info(struct port_attributes *lp_info) printf(" MaxFrameSize: %s\n", lp_info->maxframe_size); - printf(" FC-ID (Port ID): 0x%s\n", + printf(" FC-ID (Port ID): %s\n", lp_info->port_id); printf(" State: %s\n", @@ -200,403 +198,68 @@ static void show_port_info(struct port_attributes *lp_info) } static void show_target_info(const char *symbolic_name, - HBA_PORTATTRIBUTES *rp_info) + struct port_attributes *rp_info) { - char buf[256]; - int tgt_id; - int rc; char *ifname; ifname = get_ifname_from_symbolic_name(symbolic_name); - rc = sa_sys_read_line(rp_info->OSDeviceName, "roles", buf, sizeof(buf)); - if (rc) - strncpy(buf, "Unknown", sizeof(buf)); printf(" Interface: %s\n", ifname); - printf(" Roles: %s\n", buf); - - printf(" Node Name: 0x"); - show_wwn(rp_info->NodeWWN.wwn); - printf("\n"); - - printf(" Port Name: 0x"); - show_wwn(rp_info->PortWWN.wwn); - printf("\n"); - - rc = sa_sys_read_int(rp_info->OSDeviceName, "scsi_target_id", &tgt_id); - printf(" Target ID: "); - if (rc) - printf("Unknown\n"); - else if (tgt_id != -1) - printf("%d\n", tgt_id); - else - printf("Unset\n"); - - printf(" MaxFrameSize: %d\n", rp_info->PortMaxFrameSize); - - printf(" OS Device Name: %s\n", - strrchr(rp_info->OSDeviceName, '/') + 1); - - printf(" FC-ID (Port ID): 0x%06X\n", rp_info->PortFcId); - - sa_enum_decode(buf, sizeof(buf), port_states, rp_info->PortState); - printf(" State: %s\n", buf); + printf(" Roles: %s\n", rp_info->roles); + printf(" Node Name: %s\n", rp_info->node_name); + printf(" Port Name: %s\n", rp_info->port_name); + printf(" Target ID: %s\n", rp_info->scsi_target_id); + printf(" MaxFrameSize: %s\n", rp_info->maxframe_size); + printf(" OS Device Name: %s\n", rp_info->device_name); + printf(" FC-ID (Port ID): %s\n", rp_info->port_id); + printf(" State: %s\n", rp_info->port_state); printf("\n"); } static void -show_sense_data(char *dev, char *sense, int slen) -{ - printf("%s", dev); - if (slen >= 3) - printf(" Sense Key=0x%02x", sense[2]); - if (slen >= 13) - printf(" ASC=0x%02x", sense[12]); - if (slen >= 14) - printf(" ASCQ=0x%02x\n", sense[13]); - printf("\n"); -} - -#ifdef TEST_HBAAPI_V1 -static HBA_STATUS -get_inquiry_data_v1(HBA_HANDLE hba_handle, - HBA_FCPSCSIENTRY *ep, - char *inqbuf, size_t inqlen) -{ - char sense[128]; - HBA_UINT32 rlen; - HBA_UINT32 slen; - HBA_STATUS status; - - memset(inqbuf, 0, inqlen); - memset(sense, 0, sizeof(sense)); - rlen = (HBA_UINT32) inqlen; - slen = (HBA_UINT32) sizeof(sense); - status = HBA_SendScsiInquiry(hba_handle, - ep->FcpId.PortWWN, - ep->FcpId.FcpLun, - 0, - 0, - inqbuf, - rlen, - sense, - slen); - if ((status != HBA_STATUS_OK) || - (rlen < MIN_INQ_DATA_SIZE)) { - fprintf(stderr, - "%s: HBA_SendScsiInquiry failed, " - "status=0x%x, rlen=%d\n", - __func__, status, rlen); - show_sense_data(ep->ScsiId.OSDeviceName, sense, slen); - return HBA_STATUS_ERROR; - } - return HBA_STATUS_OK; -} -#else -static HBA_STATUS -get_inquiry_data_v2(HBA_HANDLE hba_handle, - HBA_PORTATTRIBUTES *lp_info, - HBA_FCPSCSIENTRYV2 *ep, - char *inqbuf, size_t inqlen) +show_short_lun_info_header(void) { - char sense[128]; - HBA_UINT32 rlen; - HBA_UINT32 slen; - HBA_STATUS status; - HBA_UINT8 sstat; - - memset(inqbuf, 0, inqlen); - memset(sense, 0, sizeof(sense)); - rlen = (HBA_UINT32) inqlen; - slen = (HBA_UINT32) sizeof(sense); - sstat = SCSI_ST_GOOD; - status = HBA_ScsiInquiryV2(hba_handle, - lp_info->PortWWN, - ep->FcpId.PortWWN, - ep->FcpId.FcpLun, - 0, - 0, - inqbuf, - &rlen, - &sstat, - sense, - &slen); - if ((status != HBA_STATUS_OK) || - (sstat != SCSI_ST_GOOD) || - (rlen < MIN_INQ_DATA_SIZE)) { - fprintf(stderr, - "%s: HBA_ScsiInquiryV2 failed, " - "status=0x%x, sstat=0x%x, rlen=%d\n", - __func__, status, sstat, rlen); - if (sstat != SCSI_ST_GOOD) - show_sense_data(ep->ScsiId.OSDeviceName, sense, slen); - return HBA_STATUS_ERROR; - } - return HBA_STATUS_OK; + printf(" LUN ID Device Name Capacity " + "Block Size Description\n"); + printf(" ------ ----------- ---------- ---------- " + "----------------------------\n"); } -#endif -#ifdef TEST_HBAAPI_V1 -static HBA_STATUS -get_device_capacity_v1(HBA_HANDLE hba_handle, - HBA_FCPSCSIENTRY *ep, - char *buf, size_t len) -{ - char sense[128]; - HBA_UINT32 rlen; - HBA_UINT32 slen; - HBA_STATUS status; - int retry_count = 10; - - while (retry_count--) { - memset(buf, 0, len); - memset(sense, 0, sizeof(sense)); - rlen = (HBA_UINT32)len; - slen = (HBA_UINT32)sizeof(sense); - status = HBA_SendReadCapacity(hba_handle, - ep->FcpId.PortWWN, - ep->FcpId.FcpLun, - buf, - rlen, - sense, - slen); - if (status == HBA_STATUS_OK) - return HBA_STATUS_OK; - if (sense[2] == 0x06) - continue; - fprintf(stderr, - "%s: HBA_SendReadCapacity failed, " - "status=0x%x, slen=%d\n", - __func__, status, slen); - show_sense_data(ep->ScsiId.OSDeviceName, sense, slen); - return HBA_STATUS_ERROR; - } - /* retry count exhausted */ - return HBA_STATUS_ERROR; -} -#else -static HBA_STATUS -get_device_capacity_v2(HBA_HANDLE hba_handle, - HBA_PORTATTRIBUTES *lp_info, - HBA_FCPSCSIENTRYV2 *ep, - char *buf, size_t len) +static void sa_dir_crawl(char *dir_name, + void (*func)(char *dirname, enum disp_style style), + enum disp_style style) { - char sense[128]; - HBA_UINT32 rlen; - HBA_UINT32 slen; - HBA_STATUS status; - HBA_UINT8 sstat; - int retry_count = 10; - - while (retry_count--) { - memset(buf, 0, len); - memset(sense, 0, sizeof(sense)); - rlen = (HBA_UINT32)len; - slen = (HBA_UINT32)sizeof(sense); - sstat = SCSI_ST_GOOD; - status = HBA_ScsiReadCapacityV2(hba_handle, - lp_info->PortWWN, - ep->FcpId.PortWWN, - ep->FcpId.FcpLun, - buf, - &rlen, - &sstat, - sense, - &slen); - if ((status == HBA_STATUS_OK) && (sstat == SCSI_ST_GOOD)) - return HBA_STATUS_OK; - if (sstat == SCSI_ST_CHECK) - continue; - fprintf(stderr, - "%s: HBA_ScsiReadCapacityV2 failed, " - "status=0x%x, sstat=0x%x, slen=%d\n", - __func__, status, sstat, slen); - if (sstat != SCSI_ST_GOOD) - show_sense_data(ep->ScsiId.OSDeviceName, sense, slen); - return HBA_STATUS_ERROR; - } - /* retry count exhausted */ - return HBA_STATUS_ERROR; -} -#endif + DIR *dir; + struct dirent *dp; + void (*f)(char *dirname, enum disp_style style); + char path[1024]; -#ifdef TEST_DEV_SERIAL_NO -static HBA_STATUS -get_device_serial_number(HBA_HANDLE hba_handle, - HBA_FCPSCSIENTRYV2 *ep, - char *buf, size_t buflen) -{ - struct scsi_inquiry_unit_sn *unit_sn; - char rspbuf[256]; - char sense[128]; - HBA_UINT32 rlen; - HBA_UINT32 slen; - HBA_STATUS status; - - memset(rspbuf, 0, sizeof(rspbuf)); - memset(sense, 0, sizeof(sense)); - rlen = (HBA_UINT32) sizeof(rspbuf); - slen = (HBA_UINT32) sizeof(sense); - status = HBA_SendScsiInquiry(hba_handle, - ep->FcpId.PortWWN, - ep->FcpId.FcpLun, - SCSI_INQF_EVPD, - SCSI_INQP_UNIT_SN, - rspbuf, - rlen, - sense, - slen); - if (status != HBA_STATUS_OK) { - fprintf(stderr, - "%s: inquiry page 0x80 failed, status=0x%x\n", - __func__, status); - show_sense_data(ep->ScsiId.OSDeviceName, sense, slen); - return HBA_STATUS_ERROR; - } - unit_sn = (struct scsi_inquiry_unit_sn *)rspbuf; - unit_sn->is_serial[unit_sn->is_page_len] = '\0'; - sa_strncpy_safe(buf, buflen, (char *)unit_sn->is_serial, - (size_t)unit_sn->is_page_len); - return HBA_STATUS_OK; -} -#endif + f = func; -#ifdef TEST_REPORT_LUNS -static void -show_report_luns_data(char *rspbuf) -{ - struct scsi_report_luns_resp *rp; - int list_len; - net64_t *lp; - u_int64_t lun_id; - - rp = (struct scsi_report_luns_resp *)rspbuf; - list_len = net32_get(&rp->rl_len); - printf("\tTotal Number of LUNs=%lu\n", list_len/sizeof(u_int64_t)); - - for (lp = rp->rl_lun; list_len > 0; lp++, list_len -= sizeof(*lp)) { - lun_id = net64_get(lp); - if (!(lun_id & ((0xfc01ULL << 48) - 1))) - printf("\tLUN %u\n", (u_int32_t)(lun_id >> 48)); - else - printf("\tLUN %lx\n", (u_int64_t)lun_id); - } -} + dir = opendir(dir_name); + if (!dir) + return; -static HBA_STATUS -get_report_luns_data_v1(HBA_HANDLE hba_handle, HBA_FCPSCSIENTRYV2 *ep) -{ - HBA_STATUS status; - char rspbuf[512 * sizeof(u_int64_t)]; /* max 512 luns */ - char sense[128]; - HBA_UINT32 rlen; - HBA_UINT32 slen; - int retry_count = 10; - - while (retry_count--) { - memset(rspbuf, 0, sizeof(rspbuf)); - memset(sense, 0, sizeof(sense)); - rlen = (HBA_UINT32) sizeof(rspbuf); - slen = (HBA_UINT32) sizeof(sense); - status = HBA_SendReportLUNs(hba_handle, - ep->FcpId.PortWWN, - rspbuf, - rlen, - sense, - slen); - if (status == HBA_STATUS_OK) { - show_report_luns_data(rspbuf); - return HBA_STATUS_OK; - } - if (sense[2] == 0x06) + while ((dp = readdir(dir)) != NULL) { + if (dp->d_name[0] == '.' && (dp->d_name[1] == '\0' || + (dp->d_name[1] == '.' && dp->d_name[2] == '\0'))) continue; - fprintf(stderr, - "%s: HBA_SendReportLUNs failed, " - "status=0x%x, slen=%d\n", - __func__, status, slen); - show_sense_data(ep->ScsiId.OSDeviceName, sense, slen); - return HBA_STATUS_ERROR; - } - /* retry count exhausted */ - return HBA_STATUS_ERROR; -} + snprintf(path, sizeof(path), "%s/%s", dir_name, dp->d_name); -static HBA_STATUS -get_report_luns_data_v2(HBA_HANDLE hba_handle, - HBA_PORTATTRIBUTES *lp_info, - HBA_FCPSCSIENTRYV2 *ep) -{ - HBA_STATUS status; - char rspbuf[512 * sizeof(u_int64_t)]; /* max 512 luns */ - char sense[128]; - HBA_UINT32 rlen; - HBA_UINT32 slen; - HBA_UINT8 sstat; - int retry_count = 10; - - while (retry_count--) { - memset(rspbuf, 0, sizeof(rspbuf)); - memset(sense, 0, sizeof(sense)); - rlen = (HBA_UINT32) sizeof(rspbuf); - slen = (HBA_UINT32) sizeof(sense); - sstat = SCSI_ST_GOOD; - status = HBA_ScsiReportLUNsV2(hba_handle, - lp_info->PortWWN, - ep->FcpId.PortWWN, - rspbuf, - &rlen, - &sstat, - sense, - &slen); - if ((status == HBA_STATUS_OK) && (sstat == SCSI_ST_GOOD)) { - show_report_luns_data(rspbuf); - return HBA_STATUS_OK; - } - if ((sstat == SCSI_ST_CHECK) && (sense[2] == 0x06)) - continue; - fprintf(stderr, - "%s: HBA_ScsiReportLUNsV2 failed, " - "status=0x%x, sstat=0x%x, slen=%d\n", - __func__, status, sstat, slen); - if (sstat != SCSI_ST_GOOD) - show_sense_data(ep->ScsiId.OSDeviceName, sense, slen); - return HBA_STATUS_ERROR; + f(path, style); } - /* retry count exhausted */ - return HBA_STATUS_ERROR; + closedir(dir); } -#endif -static void -show_short_lun_info_header(void) +static char *format_capstr(uint64_t size, unsigned int blksize) { - printf(" LUN ID Device Name Capacity " - "Block Size Description\n"); - printf(" ------ ----------- ---------- ---------- " - "----------------------------\n"); -} - -static void -show_short_lun_info(HBA_FCP_SCSI_ENTRY *ep, char *inqbuf, - u_int32_t blksize, - u_int64_t lba) -{ - struct scsi_inquiry_std *inq = (struct scsi_inquiry_std *)inqbuf; - char vendor[10]; - char model[20]; - char capstr[32]; - char rev[16]; - u_int64_t cap; double cap_abbr; + char *capstr; + uint64_t cap; char *abbr; + int ret; - memset(vendor, 0, sizeof(vendor)); - memset(model, 0, sizeof(model)); - memset(capstr, 0, sizeof(capstr)); - memset(rev, 0, sizeof(rev)); - - /* Get device capacity */ - cap = (u_int64_t)blksize * lba; + cap = size * blksize; cap_abbr = cap / (1024.0 * 1024.0); abbr = "MiB"; @@ -612,323 +275,228 @@ show_short_lun_info(HBA_FCP_SCSI_ENTRY *ep, char *inqbuf, cap_abbr /= 1024.0; abbr = "PiB"; } - snprintf(capstr, sizeof(capstr), "%0.2f %s", cap_abbr, abbr); - /* Get the device description */ - sa_strncpy_safe(vendor, sizeof(vendor), - inq->is_vendor_id, sizeof(inq->is_vendor_id)); - sa_strncpy_safe(model, sizeof(model), - inq->is_product, sizeof(inq->is_product)); - sa_strncpy_safe(rev, sizeof(rev), inq->is_rev_level, - sizeof(inq->is_rev_level)); + ret = asprintf(&capstr, "%0.2f %s", cap_abbr, abbr); + if (ret == -1) + return "Unknown"; - /* Show the LUN info */ - printf("%10d %-11s %10s %7d %s %s (rev %s)\n", - ep->ScsiId.ScsiOSLun, ep->ScsiId.OSDeviceName, - capstr, blksize, - vendor, model, rev); + return capstr; } -static void -show_full_lun_info(UNUSED HBA_HANDLE hba_handle, - HBA_PORTATTRIBUTES *lp_info, - HBA_PORTATTRIBUTES *rp_info, - HBA_FCP_SCSI_ENTRY *ep, - char *inqbuf, - u_int32_t blksize, - u_int64_t lba) +static void show_full_lun_info(unsigned int hba, unsigned int port, + unsigned int tgt, unsigned int lun) { - struct scsi_inquiry_std *inq = (struct scsi_inquiry_std *)inqbuf; - char vendor[10]; - char model[20]; - char capstr[32]; - char rev[16]; - double cap_abbr; - char *abbr; - u_int64_t cap; - u_int32_t tgt_id; - u_int8_t pqual; -#ifdef TEST_DEV_SERIAL_NO - HBA_STATUS status; - char serial_number[32]; -#endif + char vendor[256]; + char model[256]; + char rev[256]; + char *osname; + char *capstr; + uint64_t lba = 0; + uint32_t blksize = 0; + char path[1024]; + char npath[1024]; + DIR *dir; + struct dirent *dp; + struct port_attributes *rport_attrs; + struct port_attributes *port_attrs; - memset(vendor, 0, sizeof(vendor)); - memset(model, 0, sizeof(model)); - memset(capstr, 0, sizeof(capstr)); - memset(rev, 0, sizeof(rev)); + snprintf(path, sizeof(path), + "/sys/class/scsi_device/%u:%u:%u:%u", + hba, port, tgt, lun); - /* Get device description */ - sa_strncpy_safe(vendor, sizeof(vendor), - inq->is_vendor_id, sizeof(inq->is_vendor_id)); - sa_strncpy_safe(model, sizeof(model), - inq->is_product, sizeof(inq->is_product)); - sa_strncpy_safe(rev, sizeof(rev), inq->is_rev_level, - sizeof(inq->is_rev_level)); + rport_attrs = get_rport_attribs_by_device(path); + if (!rport_attrs) + return; - /* Get device capacity */ - cap = (u_int64_t)blksize * lba; + port_attrs = get_port_attribs_by_device(path); + if (!port_attrs) + goto free_rport; - cap_abbr = cap / (1024.0 * 1024.0); - abbr = "MiB"; - if (cap_abbr >= 1024) { - cap_abbr /= 1024.0; - abbr = "GiB"; - } - if (cap_abbr >= 1024) { - cap_abbr /= 1024.0; - abbr = "TiB"; - } - if (cap_abbr >= 1024) { - cap_abbr /= 1024.0; - abbr = "PiB"; + strncat(path, "/device/", sizeof(path)); + + sa_sys_read_line(path, "rev", rev, sizeof(rev)); + sa_sys_read_line(path, "model", model, sizeof(model)); + sa_sys_read_line(path, "vendor", vendor, sizeof(vendor)); + + strncat(path, "block", sizeof(path)); + + dir = opendir(path); + if (!dir) + goto free_port; + + while ((dp = readdir(dir)) != NULL) { + if (dp->d_name[0] == '.' && (dp->d_name[1] == '\0' || + (dp->d_name[1] == '.' && dp->d_name[2] == '\0'))) + continue; + + + osname = dp->d_name; + + snprintf(npath, sizeof(npath), "%s/%s/", path, osname); + sa_sys_read_u64(npath, "size", &lba); + + snprintf(npath, sizeof(npath), "%s/%s/queue/", path, osname); + sa_sys_read_u32(npath, "hw_sector_size", &blksize); } - snprintf(capstr, sizeof(capstr), "%0.2f %s", cap_abbr, abbr); - /* Get SCSI target ID */ - sa_sys_read_u32(rp_info->OSDeviceName, - "scsi_target_id", &tgt_id); + closedir(dir); /* Show lun info */ - printf(" LUN #%d Information:\n", ep->ScsiId.ScsiOSLun); + printf(" LUN #%d Information:\n", lun); printf(" OS Device Name: %s\n", - ep->ScsiId.OSDeviceName); + osname); printf(" Description: %s %s (rev %s)\n", vendor, model, rev); - printf(" Ethernet Port FCID: 0x%06X\n", - lp_info->PortFcId); - printf(" Target FCID: 0x%06X\n", - rp_info->PortFcId); - if (tgt_id == 0xFFFFFFFFU) + printf(" Ethernet Port FCID: %s\n", + port_attrs->port_id); + printf(" Target FCID: %s\n", + rport_attrs->port_id); + if (tgt == 0xFFFFFFFFU) printf(" Target ID: (None)\n"); else - printf(" Target ID: %u\n", tgt_id); - printf(" LUN ID: %d\n", - ep->ScsiId.ScsiOSLun); + printf(" Target ID: %u\n", tgt); + printf(" LUN ID: %d\n", lun); + capstr = format_capstr(lba, blksize); printf(" Capacity: %s\n", capstr); printf(" Capacity in Blocks: %" PRIu64 "\n", lba); printf(" Block Size: %" PRIu32 " bytes\n", blksize); - pqual = inq->is_periph & SCSI_INQ_PQUAL_MASK; - if (pqual == SCSI_PQUAL_ATT) - printf(" Status: Attached\n"); - else if (pqual == SCSI_PQUAL_DET) - printf(" Status: Detached\n"); - else if (pqual == SCSI_PQUAL_NC) - printf(" Status: " - "Not capable of attachment\n"); - -#ifdef TEST_DEV_SERIAL_NO - /* Show the serial number of the device */ - status = get_device_serial_number(hba_handle, ep, - serial_number, sizeof(serial_number)); - if (status == HBA_STATUS_OK) - printf(" Serial Number: %s\n", serial_number); -#endif + printf(" Status: Attached\n"); printf("\n"); + +free_rport: + free(rport_attrs); +free_port: + free(port_attrs); } -/* Compare two LUN mappings for qsort */ -static int -lun_compare(const void *arg1, const void *arg2) +static void show_short_lun_info(unsigned int hba, unsigned int port, + unsigned int tgt, unsigned int lun) { - const HBA_FCP_SCSI_ENTRY *e1 = arg1; - const HBA_FCP_SCSI_ENTRY *e2 = arg2; - int diff; + struct dirent *dp; + char vendor[256]; + char path[1024]; + char npath[1024]; + char model[256]; + char rev[256]; + DIR *dir; + uint32_t blksize = 0; + char *capstr = "Unknown"; + char *osname = "Unknown"; + uint64_t size; + + snprintf(path, sizeof(path), + "/sys/class/scsi_device/%u:%u:%u:%u/device/", + hba, port, tgt, lun); + + sa_sys_read_line(path, "rev", rev, sizeof(rev)); + sa_sys_read_line(path, "model", model, sizeof(model)); + sa_sys_read_line(path, "vendor", vendor, sizeof(vendor)); + + strncat(path, "block", sizeof(path)); + + dir = opendir(path); + if (!dir) + return; - diff = e2->FcpId.FcId - e1->FcpId.FcId; - if (diff == 0) - diff = e1->ScsiId.ScsiOSLun - e2->ScsiId.ScsiOSLun; + while ((dp = readdir(dir)) != NULL) { + if (dp->d_name[0] == '.' && (dp->d_name[1] == '\0' || + (dp->d_name[1] == '.' && dp->d_name[2] == '\0'))) + continue; - return diff; -} -static HBA_STATUS -get_device_map(HBA_HANDLE hba_handle, HBA_PORTATTRIBUTES *lp_info, - HBA_FCP_TARGET_MAPPING **tgtmap, u_int32_t *lun_count) -{ - HBA_STATUS status; - HBA_FCP_TARGET_MAPPING *map = NULL; - HBA_FCP_SCSI_ENTRY *ep; - u_int32_t limit; - u_int32_t i; + osname = dp->d_name; -#define LUN_COUNT_START 8 /* number of LUNs to start with */ -#define LUN_COUNT_INCR 4 /* excess to allocate */ + snprintf(npath, sizeof(npath), "%s/%s/", path, osname); + sa_sys_read_u64(npath, "size", &size); - /* - * Get buffer large enough to retrieve all the mappings. - * If they don't fit, increase the size of the buffer and retry. - */ - *lun_count = 0; - limit = LUN_COUNT_START; - for (;;) { - i = (limit - 1) * sizeof(*ep) + sizeof(*map); - map = malloc(i); - if (map == NULL) { - fprintf(stderr, "%s: malloc failed\n", __func__); - return HBA_STATUS_ERROR; - } - memset((char *)map, 0, i); - map->NumberOfEntries = limit; -#ifdef TEST_HBAAPI_V1 - status = HBA_GetFcpTargetMapping(hba_handle, map); -#else - status = HBA_GetFcpTargetMappingV2( - hba_handle, lp_info->PortWWN, map); -#endif - if (map->NumberOfEntries > limit) { - limit = map->NumberOfEntries + LUN_COUNT_INCR; - free(map); - continue; - } - if (status != HBA_STATUS_OK) { - fprintf(stderr, - "%s: HBA_GetFcpTargetMappingV2 failed\n", - __func__); - free(map); - return HBA_STATUS_ERROR; - } - break; + snprintf(npath, sizeof(npath), "%s/%s/queue/", path, osname); + sa_sys_read_u32(npath, "hw_sector_size", &blksize); } - if (map == NULL) { - fprintf(stderr, "%s: map == NULL\n", __func__); - return HBA_STATUS_ERROR; - } + closedir(dir); - if (map->NumberOfEntries > limit) { - fprintf(stderr, "%s: map->NumberOfEntries=%d too big\n", - __func__, map->NumberOfEntries); - return HBA_STATUS_ERROR; - } + capstr = format_capstr(size, blksize); + + /* Show the LUN info */ + printf("%10d %-11s %10s %7d %s %s (rev %s)\n", + lun, osname, + capstr, blksize, + vendor, model, rev); - ep = map->entry; - limit = map->NumberOfEntries; + free(capstr); + return; +} - /* Sort the response by LUN number */ - qsort(ep, limit, sizeof(*ep), lun_compare); +static void list_scsi_device(char *d_name, enum disp_style style) +{ + unsigned int port; + unsigned int hba; + unsigned int tgt; + unsigned int lun; + char *last; - *lun_count = limit; - *tgtmap = map; - return HBA_STATUS_OK; + last = strrchr(d_name, '/'); + + if (sscanf(last, "/%u:%u:%u:%u", &hba, &port, &tgt, &lun) != 4) + return; + + + if (style == DISP_TARG) + show_short_lun_info(hba, port, tgt, lun); + else + show_full_lun_info(hba, port, tgt, lun); } -static void -scan_device_map(HBA_HANDLE hba_handle, - HBA_PORTATTRIBUTES *lp_info, - HBA_PORTATTRIBUTES *rp_info, - enum disp_style style) +static void search_rport_targets(char *d_name, enum disp_style style) { - HBA_STATUS status; - HBA_FCP_TARGET_MAPPING *map = NULL; - u_int32_t limit; - HBA_FCP_SCSI_ENTRY *ep; - u_int32_t i; - char *dev; - char inqbuf[256]; - struct scsi_rcap10_resp rcap_resp; - struct scsi_rcap16_resp rcap16_resp; - u_int64_t lba; - u_int32_t blksize; - int lun_count = 0; - int print_header = 0; - - status = get_device_map(hba_handle, lp_info, &map, &limit); - if (status != HBA_STATUS_OK) { - fprintf(stderr, "%s: get_device_map() failed\n", __func__); + if (!strstr(d_name, "target")) return; - } - ep = map->entry; - for (i = 0; i < limit; i++, ep++) { - if (ep->FcpId.FcId != rp_info->PortFcId) - continue; + sa_dir_crawl(d_name, list_scsi_device, style); +} - dev = ep->ScsiId.OSDeviceName; - if (strstr(dev, "/dev/") == dev) - dev += 5; +static void list_luns_by_rport(char *rport, enum disp_style style) +{ + char path[1024]; + char link[1024]; + char *substr; + int len; + int ret; - /* Issue standard inquiry */ -#ifdef TEST_HBAAPI_V1 - status = get_inquiry_data_v1(hba_handle, ep, - inqbuf, sizeof(inqbuf)); -#else - status = get_inquiry_data_v2(hba_handle, lp_info, - ep, inqbuf, sizeof(inqbuf)); -#endif - if (status != HBA_STATUS_OK) - continue; - lun_count++; + snprintf(path, sizeof(path), "/sys/class/fc_remote_ports/%s", rport); - /* Issue read capacity */ -#ifdef TEST_HBAAPI_V1 - status = get_device_capacity_v1(hba_handle, ep, - (char *)&rcap_resp, - sizeof(rcap_resp)); -#else - status = get_device_capacity_v2(hba_handle, lp_info, - ep, (char *)&rcap_resp, - sizeof(rcap_resp)); -#endif - if (status != HBA_STATUS_OK) - continue; + ret = readlink(path, link, sizeof(link)); + if (ret== -1) + return; - if (net32_get(&rcap_resp.rc_lba) == 0xFFFFFFFFUL) { - /* Issue read capacity (16) */ -#ifdef TEST_HBAAPI_V1 - status = get_device_capacity_v1(hba_handle, ep, - (char *)&rcap16_resp, - sizeof(rcap16_resp)); -#else - status = get_device_capacity_v2(hba_handle, lp_info, - ep, (char *)&rcap16_resp, - sizeof(rcap16_resp)); -#endif - if (status != HBA_STATUS_OK) - continue; - - blksize = net32_get(&rcap16_resp.rc_block_len); - lba = (u_int64_t)net64_get(&rcap16_resp.rc_lba); - } else { - blksize = net32_get(&rcap_resp.rc_block_len); - lba = (u_int64_t)net32_get(&rcap_resp.rc_lba); - } + if (link[ret] != '\0') + link[ret] = '\0'; - /* Total Number of Blocks */ - lba = lba + 1; + substr = strstr(link, "net"); + snprintf(path, sizeof(path), "/sys/class/%s", substr); - switch (style) { - case DISP_TARG: - if (!print_header) { - show_short_lun_info_header(); - print_header = 1; - } - show_short_lun_info(ep, inqbuf, blksize, lba); - break; - case DISP_LUN: - show_full_lun_info(hba_handle, lp_info, - rp_info, ep, inqbuf, blksize, lba); - break; - } + substr = strstr(path, "fc_remote_ports"); -#ifdef TEST_REPORT_LUNS - if (i == 0) { /* only issue report luns to the first LUN */ -#ifdef TEST_HBAAPI_V1 - get_report_luns_data_v1(hba_handle, ep); -#else - get_report_luns_data_v2(hba_handle, lp_info, ep); -#endif - } -#endif - } + len = strlen(path) - strlen(substr); + path[len] = '\0'; + + sa_dir_crawl(path, search_rport_targets, style); + + return; +} + +static void scan_device_map(char *port, char *rport, enum disp_style style) +{ + if (style == DISP_TARG) + show_short_lun_info_header(); + + list_luns_by_rport(rport, style); /* Newline at the end of the short lun report */ if (style == DISP_TARG) printf("\n"); - - free(map); } static void show_port_stats_header(const char *ifname, int interval) @@ -1186,7 +754,7 @@ out: return rc; } -static enum fcoe_status display_one_adapter_info(const char *ifname) +static enum fcoe_status display_one_adapter_info(char *ifname) { struct port_attributes *port_attrs; struct hba_info *hba_info; @@ -1234,7 +802,7 @@ static int search_fc_adapter(struct dirent *dp, void *arg) return 0; } -enum fcoe_status display_adapter_info(const char *ifname) +enum fcoe_status display_adapter_info(char *ifname) { enum fcoe_status rc = SUCCESS; int num_hbas; @@ -1254,101 +822,161 @@ enum fcoe_status display_adapter_info(const char *ifname) return rc; } -enum fcoe_status display_target_info(const char *ifname, - enum disp_style style) + +static char *get_ifname_from_rport(char *rport) { - HBA_STATUS retval; - HBA_PORTATTRIBUTES rport_attrs; - struct hba_name_table_list *hba_table_list = NULL; - int i, num_hbas = 0; - unsigned int target_index; + char link[1024]; + char ifname[32]; + ssize_t ret; + char *path; + char *offs; + int err; + int i = 0; + + err = asprintf(&path, "%s/%s", "/sys/class/fc_remote_ports", rport); + if (err == -1) + return false; + + ret = readlink(path, link, sizeof(link)); + free(path); + if (ret == -1) + return false; + + if (link[ret] != '\0') + link[ret] = '\0'; + + offs = strstr(link, "/net/"); + + offs = offs + 5; + + for (i = 0; offs[i] != '\0'; i++) + if (offs[i] == '/') + break; + + strncpy(ifname, offs, i); + if (ifname[i] != '\0') + ifname[i] = '\0'; + + return strdup(ifname); +} + +static enum fcoe_status display_one_target_info(char *ifname, char *rport, + enum disp_style style) +{ + struct port_attributes *rport_attrs; + struct port_attributes *port_attrs; enum fcoe_status rc = SUCCESS; - HBA_HANDLE hba_handle; - HBA_PORTATTRIBUTES *port_attrs; + char *host; - if (fcoeadm_loadhba()) - return EHBAAPIERR; + rport_attrs = get_rport_attribs(rport); + if (!rport_attrs) + return EINTERR; - num_hbas = hba_table_list_init(&hba_table_list); - if (!num_hbas) - goto out; + /* + * Skip any targets that are not FCP targets + */ + if (is_fcp_target(rport_attrs)) + goto free_rport_attribs; - if (num_hbas < 0) { - rc = EINTERR; - goto out; - } + rc = EINTERR; + host = get_host_from_netdev(ifname); + if (!host) + goto free_rport_attribs; + + port_attrs = get_port_attribs(host); + if (!port_attrs) + goto free_host; + + show_target_info(port_attrs->symbolic_name, + rport_attrs); + + if (strncmp(port_attrs->port_state, "Online", 6)) + goto free_port_attribs; /* - * Loop through each HBA entry and for each serial number - * not already printed print the header and each sub-port - * on that adapter. + * This will print the LUN table + * under the target. */ - for (i = 0 ; i < num_hbas ; i++) { - if (hba_table_list->hba_table[i].failed || - hba_table_list->hba_table[i].displayed) - continue; + scan_device_map(ifname, rport, style); - hba_handle = hba_table_list->hba_table[i].hba_handle; - port_attrs = &hba_table_list->hba_table[i].port_attrs; +free_port_attribs: + free(port_attrs); +free_host: + free(host); +free_rport_attribs: + free(rport_attrs); - if (ifname && check_symbolic_name_for_interface( - port_attrs->PortSymbolicName, - ifname)) { - /* - * Overloading 'displayed' to indicate - * that the HBA/Port should be skipped. - */ - hba_table_list->hba_table[i].displayed = 1; - continue; - } + return rc; +} - for (target_index = 0; - target_index < port_attrs->NumberofDiscoveredPorts; - target_index++) { - - /* TODO: Second arg might be incorrect */ - retval = HBA_GetDiscoveredPortAttributes( - hba_handle, - 0, target_index, - &rport_attrs); - - if (retval != HBA_STATUS_OK) { - fprintf(stderr, - "HBA_GetDiscoveredPortAttributes " - "failed for target_index=%d, " - "status=%d\n", target_index, retval); - hba_table_list->hba_table[i].failed = 1; - continue; - } - - /* - * Skip any targets that are not FCP targets - */ - if (is_fcp_target(&rport_attrs)) - continue; - - show_target_info( - port_attrs->PortSymbolicName, - &rport_attrs); - - if (port_attrs->PortState != HBA_PORTSTATE_ONLINE) - continue; - - /* - * This will print the LUN table - * under the target. - */ - scan_device_map(hba_handle, - port_attrs, - &rport_attrs, style); - } +static bool rport_is_child(const char *rport, const char *ifname) +{ + + char link[1024]; + ssize_t ret; + char *path; + char *offs; + int err; + + err = asprintf(&path, "%s/%s", "/sys/class/fc_remote_ports", rport); + if (err == -1) + return false; + + ret = readlink(path, link, sizeof(link)); + free(path); + if (ret == -1) + return false; + + offs = strstr(link, ifname); + + return offs ? true : false; +} + +static int search_rports(struct dirent *dp, void *arg) +{ + struct target_info_arguments *ta; + bool allocated = false; /* ifname is malloc()ed? */ + char *ifname; + char *rport; + + + ta = arg; + rport = dp->d_name; + ifname = ta->ifname; + + if (ifname) { + bool child; + + child = rport_is_child(rport, ifname); + if (!child) + return 0; + } else { + ifname = get_ifname_from_rport(rport); + if (!ifname) + return -ENOMEM; + allocated = true; } - hba_table_list_destroy(hba_table_list); -out: - HBA_FreeLibrary(); + display_one_target_info(ifname, rport, ta->style); + + if (allocated) + free(ifname); + + return 0; +} + +enum fcoe_status display_target_info(char *ifname, + enum disp_style style) +{ + struct target_info_arguments args; + + args.ifname = ifname; + args.style = style; + + sa_dir_read("/sys/class/fc_remote_ports/", search_rports, (void *) &args); + + return SUCCESS; - return rc; } static struct sa_table fcoe_ctlr_table; diff --git a/fcoeadm_display.h b/fcoeadm_display.h index 358abf3..689c6bc 100644 --- a/fcoeadm_display.h +++ b/fcoeadm_display.h @@ -27,9 +27,9 @@ enum disp_style { DISP_TARG, }; -enum fcoe_status display_adapter_info(const char *ifname); +enum fcoe_status display_adapter_info(char *ifname); enum fcoe_status display_fcf_info(const char *ifname); -enum fcoe_status display_target_info(const char *ifname, +enum fcoe_status display_target_info(char *ifname, enum disp_style style); enum fcoe_status display_port_stats(const char *ifname, int stat_interval); diff --git a/include/sysfs_hba.h b/include/sysfs_hba.h index 1e62477..ff6dbaf 100644 --- a/include/sysfs_hba.h +++ b/include/sysfs_hba.h @@ -42,6 +42,9 @@ struct port_attributes { char maxframe_size[256]; char port_id[256]; char port_state[256]; + char scsi_target_id[256]; + char supported_classes[256]; + char roles[256]; }; struct hba_info { @@ -58,6 +61,9 @@ struct hba_info { int get_number_of_adapters(void); struct hba_info *get_hbainfo_by_pcidev(const char *pcidev); struct port_attributes *get_port_attribs(const char *host); +struct port_attributes *get_port_attribs_by_device(char *path); +struct port_attributes *get_rport_attribs(const char *rport); +struct port_attributes *get_rport_attribs_by_device(char *path); char *get_pci_dev_from_netdev(const char *netdev); char *get_host_from_netdev(const char *netdev); diff --git a/lib/sysfs_hba.c b/lib/sysfs_hba.c index e209dc1..0da55df 100644 --- a/lib/sysfs_hba.c +++ b/lib/sysfs_hba.c @@ -34,8 +34,47 @@ #include "sysfs_hba.h" #include "fcoemon_utils.h" -#define SYSFS_HOST_DIR "/sys/class/fc_host" -#define SYSFS_NET_DIR "/sys/class/net" +#define SYSFS_HOST_DIR "/sys/class/fc_host" +#define SYSFS_NET_DIR "/sys/class/net" +#define SYSFS_RPORT_DIR "/sys/class/fc_remote_ports" + +struct port_attributes *get_port_attribs_by_device(char *path) +{ + char link[1024]; + char *host; + char *rport; + int ret; + + ret = readlink(path, link, sizeof(link)); + if (ret == -1) + return NULL; + + host = strstr(link, "host"); + rport = strstr(link, "rport"); + + host[strlen(host) - strlen(rport) - 1] = '\0'; + + return get_port_attribs(host); +} + +struct port_attributes *get_rport_attribs_by_device(char *path) +{ + char link[1024]; + char *target; + char *rport; + int ret; + + ret = readlink(path, link, sizeof(link)); + if (ret == -1) + return NULL; + + target = strstr(link, "target"); + rport = strstr(link, "rport"); + + rport[strlen(rport) - strlen(target) - 1] = '\0'; + + return get_rport_attribs(rport); +} static void get_device_serial_number(struct pci_device *dev, struct hba_info *info) @@ -221,6 +260,36 @@ struct hba_info *get_hbainfo_by_pcidev(const char *pcidev) return info; } +struct port_attributes *get_rport_attribs(const char *rport) +{ + struct port_attributes *pa; + char *path; + int err; + + err = asprintf(&path,"%s/%s", SYSFS_RPORT_DIR, rport); + if (err == -1) + return NULL; + + pa = calloc(1, sizeof(*pa)); + if (!pa) + goto free_path; + + strncpy(pa->device_name, rport, sizeof(pa->device_name)); + sa_sys_read_line(path, "node_name", pa->node_name, sizeof(pa->node_name)); + sa_sys_read_line(path, "port_name", pa->port_name, sizeof(pa->port_name)); + sa_sys_read_line(path, "port_id", pa->port_id, sizeof(pa->port_id)); + sa_sys_read_line(path, "scsi_target_id", pa->scsi_target_id, sizeof(pa->scsi_target_id)); + sa_sys_read_line(path, "maxframe_size", pa->maxframe_size, sizeof(pa->maxframe_size)); + sa_sys_read_line(path, "port_state", pa->port_state, sizeof(pa->port_state)); + sa_sys_read_line(path, "supported_classes", pa->supported_classes, sizeof(pa->supported_classes)); + sa_sys_read_line(path, "roles", pa->roles, sizeof(pa->roles)); + +free_path: + free(path); + + return pa; +} + struct port_attributes *get_port_attribs(const char *host) { struct port_attributes *pa; -- 2.4.6
Locations
Projects
Search
Status Monitor
Help
OpenBuildService.org
Documentation
API Documentation
Code of Conduct
Contact
Support
@OBShq
Terms
openSUSE Build Service is sponsored by
The Open Build Service is an
openSUSE project
.
Sign Up
Log In
Places
Places
All Projects
Status Monitor