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

Reply via email to