On Tue, 2015-10-06 at 17:12 -0700, Vasu Dev wrote:
> On Mon, 2015-10-05 at 12:35 +0200, Johannes Thumshirn wrote:
> > Add sysfs_hba to to fcoemon_utils. This is the 1st part of
> > obsoleting
> > libHBAAPI2 and libhbalinux2 for fcoe-utils.
> >
> > Signed-off-by: Johannes Thumshirn <[email protected]>
> > ---
> > Makefile.am | 7 +-
> > configure.ac | 3 +
> > fcoe-utils.spec.in | 2 +-
> > include/sysfs_hba.h | 62 ++++++++
> > lib/sysfs_hba.c | 426
> > ++++++++++++++++++++++++++++++++++++++++++++++++++++
> > 5 files changed, 496 insertions(+), 4 deletions(-)
> > create mode 100644 include/sysfs_hba.h
> > create mode 100644 lib/sysfs_hba.c
> >
> > diff --git a/Makefile.am b/Makefile.am
> > index c6599ef..59c197d 100644
> > --- a/Makefile.am
> > +++ b/Makefile.am
> > @@ -9,7 +9,7 @@ AM_CFLAGS = -Wall -Wformat=2 -Werror -Wmissing
> > -prototypes -Wstrict-prototypes
> >
> > ## rules for building fcoeadm
> > fcoeadm_SOURCES = fcoeadm.c fcoeadm_display.c
> > -fcoeadm_LDADD = lib/libutil.a libopenfcoe.a $(HBAAPI_LIBS)
> > +fcoeadm_LDADD = lib/libutil.a libopenfcoe.a $(PCIACCESS_LIBS)
> > $(HBAAPI_LIBS)
> > fcoeadm_CFLAGS = $(AM_CFLAGS) $(HBAAPI_CFLAGS)
> >
> > ## rules for building fcoemon
> > @@ -29,7 +29,8 @@ fipvlan_LDADD = lib/libutil.a
> > AUTOMAKE_OPTIONS=subdir-objects
> > noinst_LIBRARIES = lib/libutil.a libopenfcoe.a
> > lib_libutil_a_SOURCES = lib/fcoe_utils.c lib/sa_log.c
> > lib/sa_select.c \
> > - lib/sa_timer.c lib/sa_other.c lib/fip.c lib/rtnetlink.c
> > lib/sa_sys.c
> > + lib/sa_timer.c lib/sa_other.c lib/fip.c lib/rtnetlink.c
> > lib/sa_sys.c \
> > + lib/sysfs_hba.c
> > libopenfcoe_a_SOURCES = libopenfcoe.c
> >
> > ## header files that need to be distributed
> > @@ -38,7 +39,7 @@ noinst_HEADERS = fcoeadm_display.h fcoe_clif.h
> > fcoemon.h \
> > include/fc_types.h include/fip.h include/net_types.h
> > include/rtnetlink.h \
> > include/libopenfcoe.h include/scsi_netlink_fc.h
> > include/scsi_netlink.h \
> > include/strarr.h include/fc_ns.h include/fc_gs.h
> > include/fc_els.h include/scsi_bsg_fc.h \
> > - include/linux/rtnetlink.h include/linux/types.h
> > include/linux/dcbnl.h
> > + include/sysfs_hba.h include/linux/rtnetlink.h
> > include/linux/types.h include/linux/dcbnl.h
> >
> > ## install configuration file in $(prefix)/etc/fcoe
> > fcoe_configdir = ${sysconfdir}/fcoe
> > diff --git a/configure.ac b/configure.ac
> > index ef0ffb1..5bafef3 100644
> > --- a/configure.ac
> > +++ b/configure.ac
> > @@ -17,6 +17,9 @@ AC_SUBST([LLDPAD_CFLAGS])
> > PKG_CHECK_MODULES([LIBHBALINUX], [libhbalinux >= 1.0.17])
> > AC_SUBST([LIBHBALINUX_CFLAGS])
> >
> > +PKG_CHECK_MODULES([PCIACCESS], [pciaccess])
> > +AC_SUBST([PCIACCESS_LIBS])
> > +
> > PKG_PROG_PKG_CONFIG
> > AC_ARG_WITH([systemdsystemunitdir],
> > AS_HELP_STRING([--with-systemdsystemunitdir=DIR],
> > diff --git a/fcoe-utils.spec.in b/fcoe-utils.spec.in
> > index d45b84b..dff3fbd 100644
> > --- a/fcoe-utils.spec.in
> > +++ b/fcoe-utils.spec.in
> > @@ -9,7 +9,7 @@ URL: http://www.open-fcoe.org
> > Source0:
> > http://www.open-fcoe.org/openfc/%{name}-%{version}.tar.gz
> > BuildRoot: %{_tmppath}/%{name}-%{version}-%{release}-root
> > -%(%{__id_u} -n)
> >
> > -BuildRequires: libHBAAPI-devel lldpad-devel
> > +BuildRequires: libHBAAPI-devel lldpad-devel libpciaccess0
> > Requires: lldpad
> > Requires(post): chkconfig
> > Requires(preun): chkconfig initscripts
> > diff --git a/include/sysfs_hba.h b/include/sysfs_hba.h
> > new file mode 100644
> > index 0000000..3038813
> > --- /dev/null
> > +++ b/include/sysfs_hba.h
> > @@ -0,0 +1,62 @@
> > +/*
>
>
>
> > + * Copyright(c) 2015 SUSE GmbH. All rights reserved.
> > + *
> > + * This program is free software; you can redistribute it and/or
> > modify it
> > + * under the terms and conditions of the GNU General Public
> > License,
> > + * version 2, as published by the Free Software Foundation.
> > + *
> > + * This program is distributed in the hope it will be useful, but
> > WITHOUT
> > + * ANY WARRANTY; without even the implied warranty of
> > MERCHANTABILITY or
> > + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public
> > License for
> > + * more details.
> > + *
> > + * Maintained at www.Open-FCoE.org
> > + */
> > +
> > +#ifndef _SYSFS_HBA_H
> > +#define _SYSFS_HBA_H
> > +
> > +#include <stdint.h>
> > +
> > +#define SYSFS_HOST_DIR "/sys/class/fc_host"
> > +#define SYSFS_NET_DIR "/sys/class/net"
> > +
> > +#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 */
> > +
> > +struct port_attributes {
> > + char device_name[256];
> > + char symbolic_name[256];
> > + char node_name[256];
> > + char port_name[256];
> > + char fabric_name[256];
> > + char speed[256];
> > + char supported_speeds[256];
> > + char maxframe_size[256];
> > + char port_id[256];
> > + char port_state[256];
> > +};
> > +
> > +struct hba_info {
> > + char manufacturer[64];
> > + char serial_number[64];
> > + char model_description[256];
> > + char hardware_version[256];
> > + char driver_name[256];
> > + char driver_version[256];
> > + uint32_t nports;
> > +};
> > +
> > +
> > +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);
> > +char *get_pci_dev_from_netdev(const char *netdev);
> > +char *get_host_from_netdev(const char *netdev);
> > +
> > +#endif /* _SYSFS_HBA_H */
> > diff --git a/lib/sysfs_hba.c b/lib/sysfs_hba.c
> > new file mode 100644
> > index 0000000..b774361
> > --- /dev/null
> > +++ b/lib/sysfs_hba.c
> > @@ -0,0 +1,426 @@
> > +/*
> > + * Copyright(c) 2015 SUSE GmbH. All rights reserved.
>
> I see mostly libhbalinux/pci.c code moved here and then new code from
> you, it is good consolidation under single file but then original
> Copyright needs to carried forward here as:-
>
> "* Copyright (c) 2008, Intel Corporation."
>
Sure, just forgot to copy it over.
> > + *
> > + * This program is free software; you can redistribute it and/or
> > modify it
> > + * under the terms and conditions of the GNU General Public
> > License,
> > + * version 2, as published by the Free Software Foundation.
> > + *
> > + * This program is distributed in the hope it will be useful, but
> > WITHOUT
> > + * ANY WARRANTY; without even the implied warranty of
> > MERCHANTABILITY or
> > + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public
> > License for
> > + * more details.
> > + *
> > + * Maintained at www.Open-FCoE.org
> > + */
> > +
> > +#define _GNU_SOURCE
> > +
> > +#include <linux/pci_regs.h>
> > +#include <sys/types.h>
> > +#include <sys/stat.h>
> > +#include <dirent.h>
> > +#include <errno.h>
> > +#include <stdlib.h>
> > +#include <string.h>
> > +#include <stdio.h>
> > +#include <stdint.h>
> > +#include <inttypes.h>
> > +#include <unistd.h>
> > +#include <pciaccess.h>
> > +
> > +#include "sysfs_hba.h"
> > +#include "fcoemon_utils.h"
> > +
> > +static void get_device_serial_number(struct pci_device *dev,
> > + struct hba_info *info)
> > +{
> > + uint32_t pcie_cap_header;
> > + uint32_t dword_high = 0;
> > + uint32_t dword_low = 0;
> > + uint16_t pcie_cap_id;
> > + pciaddr_t offset;
> > + uint16_t status;
> > + uint8_t cap_ptr;
> > + int rc;
> > +
> > + /* Default */
> > + snprintf(info->serial_number, sizeof(info->serial_number),
> > "Unknown");
> > +
> > + /*
> > + * Read the Status Regiser in the PCIe configuration
> > + * header space to see if the PCI Capability List is
> > + * supported by this device.
> > + */
> > + rc = pci_device_cfg_read_u16(dev, &status, PCI_STATUS);
> > + if (rc) {
> > + fprintf(stderr, "Failed reading PCI status
> > register\n");
> > + return;
> > + }
> > +
> > + if (!(status & PCI_STATUS_CAP_LIST)) {
> > + fprintf(stderr, "PCI capabilities are not
> > supported\n");
> > + return;
> > + }
> > +
> > + /*
> > + * Read the offset (cap_ptr) of first entry in the
> > capability list in
> > + * the PCI configuration space.
> > + */
> > + rc = pci_device_cfg_read_u8(dev, &cap_ptr,
> > PCI_CAPABILITY_LIST);
> > + if (rc) {
> > + fprintf(stderr,
> > + "Failed reading PCI Capability List
> > Register\n");
> > + return;
> > + }
> > + offset = cap_ptr;
> > +
> > + /* Search for the PCIe capability */
> > + while (offset) {
> > + uint8_t next_cap;
> > + uint8_t cap_id;
> > +
> > + rc = pci_device_cfg_read_u8(dev, &cap_id,
> > + offset +
> > PCI_CAP_LIST_ID);
> > + if (rc) {
> > + fprintf(stderr,
> > + "Failed reading capability ID at
> > 0x%"PRIx64"\n",
> > + offset + PCI_CAP_LIST_ID);
> > + return;
> > + }
> > +
> > + if (cap_id != PCI_CAP_ID_EXP) {
> > + rc = pci_device_cfg_read_u8(dev,
> > &next_cap,
> > + offset +
> > PCI_CAP_LIST_NEXT);
> > + if (rc) {
> > + fprintf(stderr,
> > + "Failed reading next
> > capability ID at 0x%"PRIx64"\n",
> > + offset +
> > PCI_CAP_LIST_NEXT);
> > + return;
> > + }
> > +
> > + offset = (pciaddr_t) next_cap;
> > + continue;
> > + }
> > +
> > + /*
> > + * PCIe Capability Structure exists!
> > + */
>
> Use tabs instead spaces...I think these worth fixing while strings
> longer than 80 if fine as talked. Just did you miss refresh since I
> see
> still patches has quite a bit checkpatch issues ? Like this one:-
>
Actually I did a checkpatch cleanup of all the patches for v4. Not sure
what went wrong here, but sure I'll have to fix that up.
> ERROR: code indent should use tabs where possible
> #259: FILE: lib/sysfs_hba.c:105:
> + /*$
>
> ERROR: code indent should use tabs where possible
> #260: FILE: lib/sysfs_hba.c:106:
> + * PCIe Capability Structure exists!$
>
> ERROR: code indent should use tabs where possible
> #261: FILE: lib/sysfs_hba.c:107:
> + */$
>
> ERROR: code indent should use tabs where possible
> #264: FILE: lib/sysfs_hba.c:110:
> + * The first PCIe extended capability is located at$
>
> ERROR: code indent should use tabs where possible
> #265: FILE: lib/sysfs_hba.c:111:
> + * offset 0x100 in the device configuration space.$
>
> ERROR: code indent should use tabs where possible
> #266: FILE: lib/sysfs_hba.c:112:
> + */$
>
> WARNING: unchecked sscanf return value
> #383: FILE: lib/sysfs_hba.c:229:
> + sscanf(pcidev, "%x:%x:%x.%x", &match.domain, &match.bus,
> &match.dev,
> + &match.func);
>
> total: 6 errors, 8 warnings, 530 lines checked
>
> Following more patches with:
> WARNING: quoted string split across lines
> #276: FILE: fcoeadm_display.c:223:
> + printf(" LUN ID Device Name Capacity "
> + "Block Size Description\n");
>
> WARNING: quoted string split across lines
> #278: FILE: fcoeadm_display.c:225:
> + printf(" ------ ----------- ---------- ---------- "
> + "----------------------------\n");
>
> WARNING: void function return statements are not generally useful
> #882: FILE: fcoeadm_display.c:430:
> + return;
> +}
>
>
> Along fixing these, coredump also needs to be fixed. The fcoeadm -i
> segfaults on two interfaces though no fault on single interface.
>
> Here is the back trace with fault in get_ctlr_num() at
> lib/sysfs_hba.c:441.
>
OK this is something I'll have to look in deeper, so probably no
refresh of the patch today.
I need to see where I can get a test setup with multiple FCoE hosts
from.
>
> Program received signal SIGSEGV, Segmentation fault.
> 0x00007ffff789b3ea in strlen () from /lib64/libc.so.6
> Missing separate debuginfos, use: debuginfo-install
> glibc-2.18-14.fc20.x86_64 libpciaccess-0.13.3-0.1.fc20.x86_64
> (gdb) bt
> #0 0x00007ffff789b3ea in strlen () from /lib64/libc.so.6
> #1 0x0000000000405ce0 in get_pci_dev_from_netdev
> (netdev=netdev@entry=0x60b123 "lo") at lib/sysfs_hba.c:441
> #2 0x0000000000402746 in display_one_adapter_info (ifname=0x60b123
> "lo") at fcoeadm_display.c:551
> #3 0x000000000040295d in search_fc_adapter (dp=<optimized out>,
> arg=<optimized out>) at fcoeadm_display.c:587
> #4 0x0000000000404fcc in sa_dir_read (dir_name=dir_name@entry=0x4074
> 1b
> "/sys/class/net/", func=func@entry=0x402950 <search_fc_adapter>,
> arg=arg@entry=0x0) at lib/sa_sys.c:181
> #5 0x0000000000403b91 in display_adapter_info (ifname=ifname@entry=0
> x0)
> at fcoeadm_display.c:604
> #6 0x00000000004020d0 in main (argc=2, argv=0x7fffffffe3a8) at
> fcoeadm.c:325
>
> > +
> > + /*
> > + * The first PCIe extended capability is located
> > at
> > + * offset 0x100 in the device configuration space.
> > + */
> > + offset = 0x100;
> > + do {
> > + rc = pci_device_cfg_read_u32(dev,
> > &pcie_cap_header,
> > + offset);
> > + if (rc) {
> > + fprintf(stderr,
> > + "Failed reading PCIe
> > config header\n");
> > + return;
> > + }
> > +
> > + /* Get the PCIe Extended Capability ID */
> > + pcie_cap_id = pcie_cap_header & 0xffff;
> > +
> > + if (pcie_cap_id != PCI_EXT_CAP_ID_DSN) {
> > + /* Get the offset of the next
> > capability */
> > + offset = (pciaddr_t)
> > pcie_cap_header >> 20;
> > + continue;
> > + }
> > +
> > + /*
> > + * Found the serial number register!
> > + */
> > +
> > + (void) pci_device_cfg_read_u32(dev,
> > &dword_low,
> > + offset +
> > 4);
> > + (void) pci_device_cfg_read_u32(dev,
> > &dword_high,
> > + offset +
> > 8);
> > + snprintf(info->serial_number,
> > + sizeof(info->serial_number),
> > + "%02X%02X%02X%02X%02X%02X\n",
> > + dword_high >> 24, (dword_high >>
> > 16) & 0xff,
> > + (dword_high >> 8) & 0xff,
> > + (dword_low >> 16) & 0xff,
> > + (dword_low >> 8) & 0xff, dword_low
> > & 0xff);
> > + break;
> > + } while (offset);
> > +
> > + break;
> > + }
> > +}
> > +
> > +static void get_pci_device_info(struct pci_device *dev, struct
> > hba_info *info)
> > +{
> > + char *unknown = "unknown";
> > + const char *vname;
> > + const char *dname;
> > + uint8_t revision;
> > +
> > + vname = pci_device_get_vendor_name(dev);
> > + if (!vname)
> > + vname = unknown;
> > +
> > + strncpy(info->manufacturer, vname, sizeof(info
> > ->manufacturer));
> > +
> > + dname = pci_device_get_device_name(dev);
> > + if (!dname)
> > + dname = unknown;
> > +
> > + strncpy(info->model_description, dname,
> > + sizeof(info->model_description));
> > +
> > + pci_device_cfg_read_u8(dev, &revision, PCI_REVISION_ID);
> > + snprintf(info->hardware_version, sizeof(info
> > ->hardware_version),
> > + "%02x", revision);
> > +
> > + info->nports = 1;
> > +
> > + get_device_serial_number(dev, info);
> > +}
> > +
> > +static void get_module_info(const char *pcidev, struct hba_info
> > *info)
> > +{
> > + char buf[1024];
> > + char *path;
> > + int err;
> > +
> > + strncpy(info->driver_name, "Unknown", sizeof(info
> > ->driver_name));
> > + strncpy(info->driver_version, "Unknown", sizeof(info
> > ->driver_version));
> > +
> > + err = asprintf(&path,
> > "/sys/bus/pci/devices/%s/driver/module", pcidev);
> > + if (err == -1)
> > + return;
> > +
> > + sa_sys_read_line(path, "version",
> > + info->driver_version, sizeof(info
> > ->driver_version));
> > +
> > + err = readlink(path, buf, sizeof(buf) - 1);
> > + free(path);
> > + if (err == -1)
> > + return;
> > +
> > + buf[err] = '\0';
> > +
> > + if (strstr(buf, "module"))
> > + strncpy(info->driver_name,
> > + strstr(buf, "module") + strlen("module") +
> > 1,
> > + sizeof(info->driver_name));
> > +
> > +}
> > +
> > +struct hba_info *get_hbainfo_by_pcidev(const char *pcidev)
> > +{
> > + struct pci_device_iterator *iterator;
> > + struct pci_slot_match match;
> > + struct pci_device *dev;
> > + struct hba_info *info;
> > + int rc;
> > +
> > + rc = pci_system_init();
> > + if (rc)
> > + return NULL;
> > +
> > + info = calloc(1, sizeof(struct hba_info));
> > + if (!info)
> > + return NULL;
> > +
> > + sscanf(pcidev, "%x:%x:%x.%x", &match.domain, &match.bus,
> > &match.dev,
> > + &match.func);
> > +
> > + iterator = pci_slot_match_iterator_create(&match);
> > + if (!iterator) {
> > + free(info);
> > + return NULL;
> > + }
> > +
> > + for (;;) {
> > + dev = pci_device_next(iterator);
> > + if (!dev)
> > + break;
> > + get_pci_device_info(dev, info);
> > + get_module_info(pcidev, info);
> > + }
> > +
> > + free(iterator);
> > + pci_system_cleanup();
> > +
> > + return info;
> > +}
> > +
> > +struct port_attributes *get_port_attribs(const char *host)
> > +{
> > + struct port_attributes *pa;
> > + char *path;
> > + int err;
> > +
> > + err = asprintf(&path, "%s/%s", SYSFS_HOST_DIR, host);
> > + if (err == -1)
> > + return NULL;
> > +
> > + pa = calloc(1, sizeof(*pa));
> > + if (!pa)
> > + goto free_path;
> > +
> > + strncpy(pa->device_name, host, sizeof(pa->device_name));
> > +
> > + sa_sys_read_line(path, "symbolic_name", pa->symbolic_name,
> > + sizeof(pa->symbolic_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, "fabric_name", pa->fabric_name,
> > + sizeof(pa->fabric_name));
> > + sa_sys_read_line(path, "speed", pa->speed, sizeof(pa
> > ->speed));
> > + sa_sys_read_line(path, "supported_speeds", pa
> > ->supported_speeds,
> > + sizeof(pa->supported_speeds));
> > + sa_sys_read_line(path, "maxframe_size", pa->maxframe_size,
> > + sizeof(pa->maxframe_size));
> > + sa_sys_read_line(path, "port_id", pa->port_id, sizeof(pa
> > ->port_id));
> > + sa_sys_read_line(path, "port_state", pa->port_state,
> > + sizeof(pa->port_state));
> > +
> > +free_path:
> > + free(path);
> > +
> > + return pa;
> > +}
> > +
> > +char *get_pci_dev_from_netdev(const char *netdev)
> > +{
> > + char buf[1024];
> > + char *pcidev;
> > + char *path;
> > + char *cp;
> > + int func;
> > + int dom;
> > + int bus;
> > + int dev;
> > + int ret;
> > +
> > + ret = asprintf(&path, "%s/%s/device", SYSFS_NET_DIR,
> > netdev);
> > + if (ret == -1)
> > + return NULL;
> > +
> > + ret = readlink(path, buf, sizeof(buf) - 1);
> > + free(path);
> > + if (ret == -1) {
> > + char realdev[256];
> > + char *subif;
> > + size_t len;
> > +
> > + subif = strchr(netdev, '.');
> > + len = strlen(netdev) - strlen(subif);
> > + strncpy(realdev, netdev, len);
> > + if (realdev[len] != '\0')
> > + realdev[len] = '\0';
> > +
> > + ret = asprintf(&path, "%s/%s/lower_%s",
> > SYSFS_NET_DIR,
> > + netdev, realdev);
> > + if (ret == -1)
> > + return NULL;
> > +
> > + ret = readlink(path, buf, sizeof(buf) - 1);
> > + free(path);
> > +
> > + if (ret == -1)
> > + return NULL;
> > + }
> > +
> > + do {
> > + cp = strrchr(buf, '/');
> > + if (!cp)
> > + break;
> > +
> > + ret = sscanf(cp + 1, "%x:%x:%x.%x", &dom, &bus,
> > &dev, &func);
> > + if (ret == 4)
> > + break;
> > +
> > + *cp = '\0';
> > + } while (cp && cp > buf);
> > +
> > + ret = asprintf(&pcidev, "%04x:%02x:%02x.%x\n", dom, bus,
> > dev, func);
> > + if (ret == -1)
> > + return NULL;
> > +
> > + return pcidev;
> > +}
> > +
> > +char *get_host_from_netdev(const char *netdev)
> > +{
> > + struct dirent *dp;
> > + char *host = NULL;
> > + char *path = NULL;
> > + DIR *dir;
> > + int ret;
> > +
> > + ret = asprintf(&path, "%s/%s/ctlr_0/", SYSFS_NET_DIR,
> > netdev);
> > + if (ret == -1)
> > + return NULL;
> > +
> > + dir = opendir(path);
> > + free(path);
> > + path = NULL;
> > +
> > + if (!dir)
> > + return NULL;
> > +
> > + for (dp = readdir(dir); dp != NULL; dp = readdir(dir)) {
> > + if (dp->d_name[0] == '.' && dp->d_name[1] == '\0')
> > + continue;
> > + if (dp->d_name[1] == '.' && dp->d_name[2] == '\0')
> > + continue;
> > +
> > + host = strstr(dp->d_name, "host");
> > + if (host) {
> > + struct stat sb;
> > +
> > + ret = asprintf(&path,
> > "%s/%s/ctlr_0/%s/fc_host/%s",
> > + SYSFS_NET_DIR, netdev, host,
> > host);
> > + if (ret == -1)
> > + goto out_closedir;
> > +
> > + ret = stat(path, &sb);
> > + free(path);
> > + path = NULL;
> > +
> > + if (ret == -1)
> > + host = NULL;
> > + break;
> > +
> > + }
> > + }
> > +
> > +out_closedir:
> > + closedir(dir);
> > +
> > + return host ? strdup(host) : NULL;
> > +}
> > +
> > +int get_number_of_adapters(void)
> > +{
> > + struct dirent *dp;
> > + int num = 0;
> > + DIR *dir;
> > +
> > + dir = opendir(SYSFS_HOST_DIR);
> > + if (!dir)
> > + return errno;
> > +
> > + for (dp = readdir(dir); dp != NULL; dp = readdir(dir)) {
> > + if (dp->d_name[0] == '.' && dp->d_name[1] == '\0')
> > + continue;
> > + if (dp->d_name[1] == '.' && dp->d_name[2] == '\0')
> > + continue;
> > +
> > + if (strstr(dp->d_name, "host"))
> > + num++;
> > +
> > + }
> > +
> > + closedir(dir);
> > +
> > + return num;
> > +}
>
>
_______________________________________________
fcoe-devel mailing list
[email protected]
http://lists.open-fcoe.org/mailman/listinfo/fcoe-devel