diff --git a/SOURCES/0001-fcoemon-netlink-buffer-resize-fix.patch b/SOURCES/0001-fcoemon-netlink-buffer-resize-fix.patch new file mode 100644 index 0000000..58c79e4 --- /dev/null +++ b/SOURCES/0001-fcoemon-netlink-buffer-resize-fix.patch @@ -0,0 +1,125 @@ +From 3b4ca6b87dae6b11da137b6afb4cf8275687d281 Mon Sep 17 00:00:00 2001 +From: Chris Leech +Date: Thu, 24 Jan 2019 18:16:47 -0800 +Subject: [PATCH] fcoemon: netlink buffer resize fix + +The recv buffer resizing for netlink messages looks to have always been +busted, it discards some of the data in the process of increasing the +buffer size. + +I've recently seen issues where the size of the netlink attributes in a +GETLINK request hit the fcm_link_buf_size window and some of the network +interfaces were ignored by fcoemon (happened mostly with recent kernels, +2 dual-port bnx2 NICs, bonding for LAN traffic on 2 ports and FCoE on +the other 2). When the ignored interface happens to be the one you want +to use for FCoE, it never gets fixed. + +This fixes the buffer resize code to use MSG_PEEK|MSG_TRUNC to check for +the needed buffer size first, and then resize with realloc when needed. +This might not actually be needed, with an 8k buffer I don't think the +kernel side will send more at once until after it sees the application +post a larger buffer, but I did force a resize and see that it worked. + +Signed-off-by: Chris Leech +--- + fcoemon.c | 54 ++++++++++++++++++------------------------------------ + 1 file changed, 18 insertions(+), 36 deletions(-) + +diff --git a/fcoemon.c b/fcoemon.c +index 9a400c56b72..9af0f1284af 100644 +--- a/fcoemon.c ++++ b/fcoemon.c +@@ -328,7 +328,6 @@ static int fcm_link_socket; + static int fcm_link_seq; + static void fcm_link_recv(void *); + static void fcm_link_getlink(void); +-static int fcm_link_buf_check(size_t); + static void clear_dcbd_info(struct fcm_netif *ff); + static int fcoe_vid_from_ifname(const char *ifname); + +@@ -354,8 +353,7 @@ char progname[20]; + * large enough to fit and expand it if we ever do a read that almost fills it. + */ + static char *fcm_link_buf; +-static size_t fcm_link_buf_size = 4096; /* initial size */ +-static const size_t fcm_link_buf_fuzz = 300; /* "almost full" remainder */ ++static size_t fcm_link_buf_size = 8192; /* initial size */ + + /* + * A value must be surrounded by quates, e.g. "x". +@@ -1848,8 +1846,22 @@ static void fcm_link_recv(UNUSED void *arg) + size_t plen; + size_t rlen; + ++ /* check to make sure our receive buffer is large enough, ++ * or scale it up as needed */ ++ rc = recv(fcm_link_socket, NULL, 0, MSG_PEEK | MSG_TRUNC); ++ if (rc > fcm_link_buf_size) { ++ FCM_LOG_DBG("resizing link buf to %d bytes\n", rc); ++ void *resize = realloc(fcm_link_buf, rc); ++ if (resize) { ++ fcm_link_buf = resize; ++ fcm_link_buf_size = rc; ++ } else { ++ FCM_LOG_ERR(errno, "Failed to allocate link buffer"); ++ } ++ } ++ + buf = fcm_link_buf; +- rc = read(fcm_link_socket, buf, fcm_link_buf_size); ++ rc = recv(fcm_link_socket, buf, fcm_link_buf_size, 0); + if (rc <= 0) { + if (rc < 0) + FCM_LOG_ERR(errno, "Error reading from " +@@ -1858,11 +1870,6 @@ static void fcm_link_recv(UNUSED void *arg) + return; + } + +- if (fcm_link_buf_check(rc)) { +- fcm_link_getlink(); +- return; +- } +- + hp = (struct nlmsghdr *)buf; + rlen = rc; + for (hp = (struct nlmsghdr *)buf; NLMSG_OK(hp, rlen); +@@ -1927,34 +1934,9 @@ static void fcm_link_getlink(void) + msg.nl.nlmsg_pid = getpid(); + msg.ifi.ifi_family = AF_UNSPEC; + msg.ifi.ifi_type = ARPHRD_ETHER; +- rc = write(fcm_link_socket, &msg, sizeof(msg)); ++ rc = send(fcm_link_socket, &msg, sizeof(msg), 0); + if (rc < 0) +- FCM_LOG_ERR(errno, "write error"); +-} +- +-/* +- * Check for whether buffer needs to grow based on amount read. +- * Free's the old buffer so don't use that after this returns non-zero. +- */ +-static int fcm_link_buf_check(size_t read_len) +-{ +- char *buf; +- size_t len = read_len; +- +- if (len > fcm_link_buf_size - fcm_link_buf_fuzz) { +- len = fcm_link_buf_size; +- len = len + len / 2; /* grow by 50% */ +- buf = malloc(len); +- if (buf != NULL) { +- free(fcm_link_buf); +- fcm_link_buf = buf; +- fcm_link_buf_size = len; +- return 1; +- } else { +- FCM_LOG_ERR(errno, "failed to allocate link buffer"); +- } +- } +- return 0; ++ FCM_LOG_ERR(errno, "send error"); + } + + static void fcm_fcoe_init(void) +-- +2.21.0 + diff --git a/SPECS/fcoe-utils.spec b/SPECS/fcoe-utils.spec index 5c5f7f4..fc08ef0 100644 --- a/SPECS/fcoe-utils.spec +++ b/SPECS/fcoe-utils.spec @@ -5,7 +5,7 @@ Name: fcoe-utils Version: 1.0.32 -Release: 6%{?dist} +Release: 7%{?dist} Summary: Fibre Channel over Ethernet utilities Group: Applications/System License: GPLv2 @@ -20,6 +20,7 @@ Patch0: fcoe-utils-gcc7-fmt-truc-err.patch Patch1: fcoe-utils-gcc8-fmt-truc-err.patch Patch2: fcoe-utils-v1.0.32-1-fcoe-utils-Fix-get_ctlr_num-for-large-ctlr_-indices.patch Patch3: fcoe-utils-set-default-DCB_REQUIRED-to-no.patch +Patch4: 0001-fcoemon-netlink-buffer-resize-fix.patch BuildRequires: autoconf BuildRequires: automake BuildRequires: libpciaccess-devel @@ -84,6 +85,9 @@ rm -f %{buildroot}/%{_sysconfdir}/fcoe/config %{_libexecdir}/fcoe/ %changelog +* Fri Dec 06 2019 Chris Leech - 1.0.32-7 +- 1776492 fcoemon: fix ignored devices from recv buffer resize bug + * Tue Aug 07 2018 Chris Leech - 1.0.32-6 - remove fcoe from SUPPORTED_DRIVERS in /etc/sysconfig/fcoe - add qedf to SUPPORTED_DRIVERS in /etc/sysconf/fcoe