Patchwork [Open-FCoE,3/8] fcoemon: Find the fcoe_cltr for an <ifname> in sysfs

login
register
mail settings
Submitter Robert Love
Date March 5, 2013, 6:29 p.m.
Message ID <20130305182959.21625.82402.stgit@fritz>
Download mbox | patch
Permalink /patch/4/
State Accepted
Headers show

Comments

Robert Love - March 5, 2013, 6:29 p.m.
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.love@intel.com>
Tested-by: Marcus Dennis <marcusx.e.dennis@intel.com>
---
 fcoemon.c            |   15 ++++++--
 include/fcoe_utils.h |    6 +++
 lib/fcoe_utils.c     |   94 +++++++++++++++++++++++++++++++++++++++++++++++++-
 3 files changed, 110 insertions(+), 5 deletions(-)

Patch

diff --git a/fcoemon.c b/fcoemon.c
index 12981f9..a25d090 100644
--- a/fcoemon.c
+++ b/fcoemon.c
@@ -136,6 +136,7 @@  struct fcoe_port {
 	int vlan_disc_count;
 	int fip_socket;
 	char fchost[FCHOSTBUFLEN];
+	char ctlr[FCHOSTBUFLEN];
 	uint32_t last_fc_event_num;
 };
 
@@ -2585,11 +2586,18 @@  static void fcm_fcoe_action(struct fcm_netif *ff, struct fcoe_port *p)
 		 * has an active fcoe session by checking for
 		 * the fc_host in sysfs.
 		 */
-		if (fcoe_find_fchost(ifname, p->fchost, FCHOSTBUFLEN))
+		if (fcoe_find_fchost(ifname, p->fchost, FCHOSTBUFLEN)) {
 			FCM_LOG_DBG("Failed to find fc_host for %s\n", p->ifname);
+			break;
+		}
+
+		if (fcoe_find_ctlr(p->fchost, p->ctlr, FCHOSTBUFLEN)) {
+			FCM_LOG_DBG("Failed to get ctlr for %s\n", p->ifname);
+			break;
+		}
 
-		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);
@@ -2861,6 +2869,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;
diff --git a/include/fcoe_utils.h b/include/fcoe_utils.h
index c0797b4..34f6a45 100644
--- a/include/fcoe_utils.h
+++ b/include/fcoe_utils.h
@@ -35,6 +35,7 @@ 
 #define MAX_STR_LEN 512
 #define MAX_PATH_LEN MAX_STR_LEN
 
+
 #define SYSFS_MOUNT                            "/sys"
 #define SYSFS_NET               SYSFS_MOUNT    "/class/net"
 #define SYSFS_FCHOST            SYSFS_MOUNT    "/class/fc_host"
@@ -82,10 +83,13 @@  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_fchost(const char *ifname, char *fchost, int len);
+enum fcoe_status fcoe_find_ctlr(const char *fchost, char *ctlr, int len);
 int fcoe_checkdir(char *dir);
 int check_symbolic_name_for_interface(const char *symbolic_name,
 				      const char *ifname);
 char *get_ifname_from_symbolic_name(const char *symbolic_name);
 int fcoe_sysfs_read(char *buf, int size, const char *path);
+enum fcoe_status fcm_write_str_to_sysfs_file(const char *path, const char *str);
+
 #endif /* _FCOE_UTILS_H_ */
diff --git a/lib/fcoe_utils.c b/lib/fcoe_utils.c
index 0ebc854..097a130 100644
--- a/lib/fcoe_utils.c
+++ b/lib/fcoe_utils.c
@@ -65,7 +65,7 @@  static int fcoe_check_fchost(const char *ifname, const char *dname)
 	return rc;
 }
 
-enum fcoe_status fcoe_find_fchost(char *ifname, char *fchost, int len)
+enum fcoe_status fcoe_find_fchost(const char *ifname, char *fchost, int len)
 {
 	int n, dname_len, status;
 	struct dirent **namelist;
@@ -193,3 +193,95 @@  int check_symbolic_name_for_interface(const char *symbolic_name,
 
 	return rc;
 }
+
+enum fcoe_status fcm_write_str_to_sysfs_file(const char *path, const char *str)
+{
+	FILE *fp = NULL;
+	enum fcoe_status ret = EFAIL;
+
+	fp = fopen(path, "w");
+	if (!fp)
+		goto err_out;
+
+	if (EOF == fputs(str, fp))
+		goto out;
+
+	ret = SUCCESS;
+out:
+	fclose(fp);
+err_out:
+	return ret;
+}
+
+static int fchost_filter(const struct dirent *dent)
+{
+	return !strncmp(dent->d_name, "host", 4);
+}
+
+static int fcoe_check_ctlr(const 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_FCOE_BUS_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(const char *fchost, char *ctlr, int len)
+{
+	int n, dname_len, status;
+	struct dirent **namelist;
+	int rc = ENOFCOECONN;
+
+	status = n = scandir(SYSFS_FCOE_BUS_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;
+}