Add support for setting priorities provided by DCB in the kernel. This
implementation does not track any priority changes which could occur
over time.

Signed-off-by: Mark Rustad <mark.d.rus...@intel.com>
---
 usr/Makefile |    4 ++
 usr/io.c     |  104 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++-
 2 files changed, 105 insertions(+), 3 deletions(-)

diff --git a/usr/Makefile b/usr/Makefile
index b02a706..991efd9 100644
--- a/usr/Makefile
+++ b/usr/Makefile
@@ -21,10 +21,12 @@ ifeq ($(OSNAME),Linux)
        endif
        endif
 IPC_OBJ=netlink.o
+DCB_OBJ=dcb_app.o
 else
 ifeq ($(OSNAME),FreeBSD)
 IPC_CFLAGS=
 IPC_OBJ=ioctl.o
+DCB_OBJ=
 endif
 endif
 
@@ -39,7 +41,7 @@ SYSDEPS_SRCS = $(wildcard ../utils/sysdeps/*.o)
 # sources shared between iscsid, iscsiadm and iscsistart
 ISCSI_LIB_SRCS = iscsi_util.o io.o auth.o login.o log.o md5.o sha1.o iface.o \
        idbm.o sysfs.o host.o session_info.o iscsi_sysfs.o iscsi_net_util.o \
-       iscsid_req.o $(SYSDEPS_SRCS)
+       iscsid_req.o $(SYSDEPS_SRCS) $(DCB_OBJ)
 # core initiator files
 INITIATOR_SRCS = initiator.o scsi.o actor.o event_poll.o mgmt_ipc.o \
                transport.o cxgbi.o be2iscsi.o
diff --git a/usr/io.c b/usr/io.c
index 8fb806d..e9017a1 100644
--- a/usr/io.c
+++ b/usr/io.c
@@ -26,11 +26,14 @@
 #include <fcntl.h>
 #include <sys/poll.h>
 #include <sys/ioctl.h>
+#include <sys/types.h>
+#include <ifaddrs.h>
 #include <netinet/tcp.h>
 #include <arpa/inet.h>
 
 #include "types.h"
 #include "iscsi_proto.h"
+#include "iscsi_settings.h"
 #include "initiator.h"
 #include "iscsi_ipc.h"
 #include "log.h"
@@ -38,6 +41,7 @@
 #include "idbm.h"
 #include "iface.h"
 #include "sysdeps.h"
+#include "dcb_app.h"
 
 #define LOG_CONN_CLOSED(conn) \
 do { \
@@ -76,6 +80,80 @@ set_non_blocking(int fd)
 
 }
 
+static int select_priority(struct iscsi_conn *conn, int pri_mask)
+{
+       int msk;
+
+       if (!pri_mask)
+               return 0;
+
+       /*
+        * TODO: Configure priority selection from the mask
+        * For now, just always take the highest
+        */
+
+       /* Find highest bit set */
+       while ((msk = pri_mask & (pri_mask - 1)))
+               pri_mask = msk;
+
+       return ffs(pri_mask) - 1;
+}
+
+static int inet_cmp_addr(struct sockaddr *s1, struct sockaddr *s2)
+{
+       struct sockaddr_in *si1 = (struct sockaddr_in *)s1;
+       struct sockaddr_in *si2 = (struct sockaddr_in *)s2;
+
+       return si1->sin_addr.s_addr != si2->sin_addr.s_addr;
+}
+
+static int inet6_cmp_addr(struct sockaddr *s1, struct sockaddr *s2)
+{
+       struct sockaddr_in6 *si1 = (struct sockaddr_in6 *)s1;
+       struct sockaddr_in6 *si2 = (struct sockaddr_in6 *)s2;
+
+       return memcmp(&si1->sin6_addr, &si2->sin6_addr, sizeof(si1->sin6_addr));
+}
+
+static char *find_ifname(struct ifaddrs *ifa, struct sockaddr *sa)
+{
+       for (; ifa; ifa = ifa->ifa_next) {
+               if (sa->sa_family != ifa->ifa_addr->sa_family)
+                       continue;
+               switch (sa->sa_family) {
+               case AF_INET:
+                       if (inet_cmp_addr(sa, ifa->ifa_addr) == 0)
+                               return ifa->ifa_name;
+                       break;
+               case AF_INET6:
+                       if (inet6_cmp_addr(sa, ifa->ifa_addr) == 0)
+                               return ifa->ifa_name;
+                       break;
+               }
+       }
+
+       return NULL;
+}
+
+static void set_dcb_priority(struct iscsi_conn *conn, const char *devname)
+{
+       int pri_mask = 0;
+
+       pri_mask = get_dcb_app_pri_by_port(devname, ISCSI_DEFAULT_PORT);
+       if (pri_mask < 0)
+               log_debug(2, "Getting priority for %s returned %d",
+                               devname, pri_mask);
+       else if (pri_mask == 0)
+               log_debug(2, "No priority for %s", devname);
+       else {
+               int pri = select_priority(conn, pri_mask);
+
+               log_debug(1, "Setting socket priority to %d", pri);
+               setsockopt(conn->socket_fd, SOL_SOCKET,
+                               SO_PRIORITY, &pri, sizeof(pri));
+       }
+}
+
 #if 0
 /* not used by anyone */
 static int get_hwaddress_from_netdev(char *netdev, char *hwaddress)
@@ -320,6 +398,10 @@ iscsi_io_tcp_connect(iscsi_conn_t *conn, int non_blocking)
        log_debug(1, "connecting to %s:%s", conn->host, serv);
        if (non_blocking)
                set_non_blocking(conn->socket_fd);
+
+       if (conn->session->netdev[0])
+               set_dcb_priority(conn, conn->session->netdev);
+
        rc = connect(conn->socket_fd, (struct sockaddr *) ss, sizeof (*ss));
        return rc;
 }
@@ -368,8 +450,9 @@ iscsi_io_tcp_poll(iscsi_conn_t *conn, int timeout_ms)
        }
 
        len = sizeof(ss);
-       if (log_level > 0 &&
-           getsockname(conn->socket_fd, (struct sockaddr *) &ss, &len) >= 0) {
+       if (log_level > 0 || !conn->session->netdev)
+               rc = getsockname(conn->socket_fd, (struct sockaddr *)&ss, &len);
+       if (log_level > 0 && rc >= 0) {
                getnameinfo((struct sockaddr *) &conn->saddr,
                            sizeof(conn->saddr), conn->host,
                            sizeof(conn->host), serv, sizeof(serv),
@@ -381,6 +464,23 @@ iscsi_io_tcp_poll(iscsi_conn_t *conn, int timeout_ms)
                log_debug(1, "connected local port %s to %s:%s",
                          lserv, conn->host, serv);
        }
+
+       if (!conn->session->netdev[0] && rc >= 0) {
+               struct ifaddrs *ifa;
+               char *ifname;
+
+               rc = getifaddrs(&ifa);
+               if (rc < 0)
+                       log_error("getifaddrs failed with %d\n", errno);
+               else {
+                       ifname = find_ifname(ifa, (struct sockaddr *)&ss);
+                       log_debug(1, "find_ifname returned %s\n", ifname);
+                       if (ifname)
+                               set_dcb_priority(conn, ifname);
+                       freeifaddrs(ifa);
+               }
+       }
+
        return 1;
 }
 

-- 
You received this message because you are subscribed to the Google Groups 
"open-iscsi" group.
To post to this group, send email to open-iscsi@googlegroups.com.
To unsubscribe from this group, send email to 
open-iscsi+unsubscr...@googlegroups.com.
For more options, visit this group at 
http://groups.google.com/group/open-iscsi?hl=en.

Reply via email to