The kernel now displays fcoe_ctlr_device represenations
in sysfs. We will need a reference to these devices in later
patches when we start using the kernel's new fcoe_sysfs
based create, destroy, enable and disable interfaces.

Signed-off-by: Robert Love <robert.w.l...@intel.com>
---
 fcoemon.c            |   80 +++++++++++++++++++++++++++++++++++++++++++++++++-
 include/fcoe_utils.h |    2 +
 2 files changed, 80 insertions(+), 2 deletions(-)

diff --git a/fcoemon.c b/fcoemon.c
index b53545d..0ec3afb 100644
--- a/fcoemon.c
+++ b/fcoemon.c
@@ -132,6 +132,7 @@ struct fcoe_port {
        int vlan_disc_count;
        int fip_socket;
        char fchost[FCHOSTBUFLEN];
+       char ctlr[FCHOSTBUFLEN];
        uint32_t last_fc_event_num;
 };
 
@@ -2594,9 +2595,11 @@ static void fcm_fcoe_action(struct fcm_netif *ff, struct 
fcoe_port *p)
                 */
                if (fcoe_find_fchost(ifname, p->fchost, FCHOSTBUFLEN))
                        FCM_LOG_DBG("Failed to find fc_host for %s\n", 
p->ifname);
+               if (fcoe_find_ctlr(p->fchost, p->ctlr, FCHOSTBUFLEN))
+                       FCM_LOG_DBG("Failed to get ctlr for %s\n", p->ifname);
 
-               FCM_LOG_DBG("OP: created fchost:%s for %s\n",
-                            p->fchost, p->ifname);
+               FCM_LOG_DBG("OP: created fchost:%s on ctlr:%s for %s\n",
+                           p->fchost, p->ctlr, p->ifname);
                break;
        case FCP_DESTROY_IF:
                FCM_LOG_DBG("OP: DESTROY %s\n", p->ifname);
@@ -2870,6 +2873,7 @@ static void fcm_dump(void)
                FCM_LOG("vlan_disc_count: %d\n", curr->vlan_disc_count);
                FCM_LOG("fip_socket: %d\n", curr->fip_socket); //TODO
                FCM_LOG("fchost: %s\n", curr->fchost);
+               FCM_LOG("ctlr: %s\n", curr->ctlr);
                FCM_LOG("last_fc_event_num: %d\n", curr->last_fc_event_num);
 
                next = curr->next;
@@ -3433,3 +3437,75 @@ static void print_errors(int errors)
 
        FCM_LOG("%s\n", msg);
 }
+
+static int fchost_filter(const struct dirent *dent)
+{
+       return !strncmp(dent->d_name, "host", 4);
+}
+
+static int fcoe_check_ctlr(char *fchost, const char *dname, int len)
+{
+       int n, status;
+       struct dirent **namelist;
+       char path[MAX_PATH_LEN];
+       int rc = -EINVAL;
+
+       sprintf(path, "%s/%s", SYSFS_DEVICES, dname);
+       status = n = scandir(path, &namelist, fchost_filter, alphasort);
+       for (n-- ; n >= 0 ; n--) {
+               if (rc) {
+                       if (!strncmp(namelist[n]->d_name, fchost, 20))
+                               rc = SUCCESS;
+                       else
+                               rc = EINTERR;
+               }
+               free(namelist[n]);
+       }
+       if (status >= 0)
+               free(namelist);
+
+       return rc;
+}
+
+static int ctlr_filter(const struct dirent *dent)
+{
+       return !strncmp(dent->d_name, "ctlr_", 5);
+}
+
+enum fcoe_status fcoe_find_ctlr(char *fchost, char *ctlr, int len)
+{
+       int n, dname_len, status;
+       struct dirent **namelist;
+       int rc = ENOFCOECONN;
+
+       status = n = scandir(SYSFS_DEVICES, &namelist, ctlr_filter, alphasort);
+       for (n-- ; n >= 0 ; n--) {
+               if (rc) {
+                       /* check ctlr against known host */
+                       if (!fcoe_check_ctlr(fchost,
+                                            namelist[n]->d_name,
+                                            len)) {
+
+                               dname_len = strnlen(namelist[n]->d_name, len);
+
+                               if (len > dname_len) {
+                                       strncpy(ctlr, namelist[n]->d_name,
+                                               dname_len + 1);
+                                       /* rc = 0 indicates found */
+                                       rc = SUCCESS;
+                               } else {
+                                       /*
+                                        * The fc_host is too large
+                                        * for the buffer.
+                                        */
+                                       rc = EINTERR;
+                               }
+                       }
+               }
+               free(namelist[n]);
+       }
+       if (status >= 0)
+               free(namelist);
+
+       return rc;
+}
diff --git a/include/fcoe_utils.h b/include/fcoe_utils.h
index ca3288c..5f99073 100644
--- a/include/fcoe_utils.h
+++ b/include/fcoe_utils.h
@@ -38,6 +38,7 @@
 #define SYSFS_MOUNT    "/sys"
 #define SYSFS_NET      SYSFS_MOUNT "/class/net"
 #define SYSFS_FCHOST   SYSFS_MOUNT "/class/fc_host"
+#define SYSFS_DEVICES   SYSFS_MOUNT "/bus/fcoe/devices"
 #define SYSFS_FCOE     SYSFS_MOUNT "/module/libfcoe/parameters"
 
 #define FCOE_CREATE    SYSFS_FCOE "/create"
@@ -77,6 +78,7 @@ enum fcoe_status {
 enum fcoe_status fcoe_validate_interface(char *ifname);
 enum fcoe_status fcoe_validate_fcoe_conn(char *ifname);
 enum fcoe_status fcoe_find_fchost(char *ifname, char *fchost, int len);
+enum fcoe_status fcoe_find_ctlr(char *fchost, char *ctlr, int len);
 int fcoe_checkdir(char *dir);
 int check_symbolic_name_for_interface(const char *symbolic_name,
                                      const char *ifname);

_______________________________________________
devel mailing list
devel@open-fcoe.org
https://lists.open-fcoe.org/mailman/listinfo/devel

Reply via email to