All of lore.kernel.org
 help / color / mirror / Atom feed
* [lustre-devel] lnet ip2nets option broken in master?
@ 2019-05-25 14:33 Chris Horn
  2019-05-27  8:48 ` Degremont, Aurelien
  0 siblings, 1 reply; 9+ messages in thread
From: Chris Horn @ 2019-05-25 14:33 UTC (permalink / raw)
  To: lustre-devel

Hi Aur?lien,

I reported this issue in a comment in LU-11838 (https://jira.whamcloud.com/browse/LU-11838?focusedCommentId=244766&page=com.atlassian.jira.plugin.system.issuetabpanels%3Acomment-tabpanel#comment-244766). James is working on patches to fix it.

FWIW, when testing master I've been reverting the following patches to fix this issue for both socklnd and o2iblnd:

d661c584c6 Revert "LU-11838 lnet: change lnet_ipaddr_enumerate() to use for_each_netdev()"
4c681cf4ee Revert "LU-11838 o2iblnd: get IP address more directly."
f4fe014620 Revert "LU-6399 lnet: socket cleanup"

Chris Horn

?On 5/24/19, 11:28 AM, "lustre-devel on behalf of Degremont, Aurelien" <lustre-devel-bounces at lists.lustre.org on behalf of degremoa@amazon.com> wrote:

    Hi all,
    
    I'm doing several tests with LNET and I realized lnet module option 'ip2nets' does not work anymore.
    I git-bisected the regression down to:
    
    commit f5991afd8779fe747778e28e998277a10242a57d
    Author: NeilBrown <neilb@suse.com>
    Date:   Mon Jan 7 14:23:19 2019 -0500
    
        LU-11838 lnet: change lnet_ipaddr_enumerate() to use for_each_netdev()
    
    
    Am I doing something wrong? Is that already known and there is some patchs around for it?
    
    Funny thing is that the normal way to use it does not work, but if I specify IP address in the reverse order, it works. (Could be just a side effect/red herring)
    
    Ie: ip2nets="tcp2(eth0) 172.32.47.137".  -> ERROR (correct IP)
    ip2net="tcp2(eth0) 137.47.32.172" -> OK
    
    I was not able to understand the bug.
    
    If it makes sense, I can open a ticket.
    
    Aur?lien
    
    _______________________________________________
    lustre-devel mailing list
    lustre-devel at lists.lustre.org
    http://lists.lustre.org/listinfo.cgi/lustre-devel-lustre.org
    

^ permalink raw reply	[flat|nested] 9+ messages in thread

* [lustre-devel] lnet ip2nets option broken in master?
  2019-05-25 14:33 [lustre-devel] lnet ip2nets option broken in master? Chris Horn
@ 2019-05-27  8:48 ` Degremont, Aurelien
  2019-05-27 18:03   ` Andreas Dilger
  2019-05-28 13:13   ` James Simmons
  0 siblings, 2 replies; 9+ messages in thread
From: Degremont, Aurelien @ 2019-05-27  8:48 UTC (permalink / raw)
  To: lustre-devel

Hi Chris,

Thanks for the info!

@James, most of the patches you were waiting for are almost landed (last ones are in master-next).
Do you have a draft of the fix for ip2nets you can push in gerrit fortestsonly?

Aur?lien

?Le 25/05/2019 16:33, ? Chris Horn ? <hornc@cray.com> a ?crit :

    Hi Aur?lien,
    
    I reported this issue in a comment in LU-11838 (https://jira.whamcloud.com/browse/LU-11838?focusedCommentId=244766&page=com.atlassian.jira.plugin.system.issuetabpanels%3Acomment-tabpanel#comment-244766). James is working on patches to fix it.
    
    FWIW, when testing master I've been reverting the following patches to fix this issue for both socklnd and o2iblnd:
    
    d661c584c6 Revert "LU-11838 lnet: change lnet_ipaddr_enumerate() to use for_each_netdev()"
    4c681cf4ee Revert "LU-11838 o2iblnd: get IP address more directly."
    f4fe014620 Revert "LU-6399 lnet: socket cleanup"
    
    Chris Horn
    
    On 5/24/19, 11:28 AM, "lustre-devel on behalf of Degremont, Aurelien" <lustre-devel-bounces at lists.lustre.org on behalf of degremoa@amazon.com> wrote:
    
        Hi all,
        
        I'm doing several tests with LNET and I realized lnet module option 'ip2nets' does not work anymore.
        I git-bisected the regression down to:
        
        commit f5991afd8779fe747778e28e998277a10242a57d
        Author: NeilBrown <neilb@suse.com>
        Date:   Mon Jan 7 14:23:19 2019 -0500
        
            LU-11838 lnet: change lnet_ipaddr_enumerate() to use for_each_netdev()
        
        
        Am I doing something wrong? Is that already known and there is some patchs around for it?
        
        Funny thing is that the normal way to use it does not work, but if I specify IP address in the reverse order, it works. (Could be just a side effect/red herring)
        
        Ie: ip2nets="tcp2(eth0) 172.32.47.137".  -> ERROR (correct IP)
        ip2net="tcp2(eth0) 137.47.32.172" -> OK
        
        I was not able to understand the bug.
        
        If it makes sense, I can open a ticket.
        
        Aur?lien
        
        _______________________________________________
        lustre-devel mailing list
        lustre-devel at lists.lustre.org
        http://lists.lustre.org/listinfo.cgi/lustre-devel-lustre.org
        
    
    

^ permalink raw reply	[flat|nested] 9+ messages in thread

* [lustre-devel] lnet ip2nets option broken in master?
  2019-05-27  8:48 ` Degremont, Aurelien
@ 2019-05-27 18:03   ` Andreas Dilger
  2019-05-28 13:05     ` Degremont, Aurelien
  2019-05-28 13:13   ` James Simmons
  1 sibling, 1 reply; 9+ messages in thread
From: Andreas Dilger @ 2019-05-27 18:03 UTC (permalink / raw)
  To: lustre-devel


On 5/24/19, 11:28 AM, "Degremont, Aurelien" <degremoa@amazon.com> wrote:
> 
>        I'm doing several tests with LNET and I realized lnet module option 'ip2nets' does not work anymore.
>        I git-bisected the regression down to:
> 
>        commit f5991afd8779fe747778e28e998277a10242a57d
>        Author: NeilBrown <neilb@suse.com>
>        Date:   Mon Jan 7 14:23:19 2019 -0500
> 
>            LU-11838 lnet: change lnet_ipaddr_enumerate() to use for_each_netdev()
> 
> 
>        Am I doing something wrong? Is that already known and there is some patchs around for it?
> 
>        Funny thing is that the normal way to use it does not work, but if I specify IP address in the reverse order, it works. (Could be just a side effect/red herring)
> 
>        Ie: ip2nets="tcp2(eth0) 172.32.47.137".  -> ERROR (correct IP)
>        ip2net="tcp2(eth0) 137.47.32.172" -> OK
> 
>        I was not able to understand the bug.
> 
>        If it makes sense, I can open a ticket.
> 
>        Aur?lien

My non-LNet-experienced thinking is that the network layer expects the IP addresses to be in big-endian always, and Lustre is supplying them in little-endian?  Maybe they just need a "htons(addr)" before calling for_each_netdev()?

Cheers, Andreas
--
Andreas Dilger
Principal Lustre Architect
Whamcloud

^ permalink raw reply	[flat|nested] 9+ messages in thread

* [lustre-devel] lnet ip2nets option broken in master?
  2019-05-27 18:03   ` Andreas Dilger
@ 2019-05-28 13:05     ` Degremont, Aurelien
  0 siblings, 0 replies; 9+ messages in thread
From: Degremont, Aurelien @ 2019-05-28 13:05 UTC (permalink / raw)
  To: lustre-devel



?Le 27/05/2019 20:03, ? Andreas Dilger ? <adilger@whamcloud.com> a ?crit :

    
    On 5/24/19, 11:28 AM, "Degremont, Aurelien" <degremoa@amazon.com> wrote:
    > 
    >        I'm doing several tests with LNET and I realized lnet module option 'ip2nets' does not work anymore.
    >        I git-bisected the regression down to:
    > 
    >        commit f5991afd8779fe747778e28e998277a10242a57d
    >        Author: NeilBrown <neilb@suse.com>
    >        Date:   Mon Jan 7 14:23:19 2019 -0500
    > 
    >            LU-11838 lnet: change lnet_ipaddr_enumerate() to use for_each_netdev()
    > 
    > 
    >        Am I doing something wrong? Is that already known and there is some patchs around for it?
    > 
    >        Funny thing is that the normal way to use it does not work, but if I specify IP address in the reverse order, it works. (Could be just a side effect/red herring)
    > 
    >        Ie: ip2nets="tcp2(eth0) 172.32.47.137".  -> ERROR (correct IP)
    >        ip2net="tcp2(eth0) 137.47.32.172" -> OK
    > 
    >        I was not able to understand the bug.
    > 
    >        If it makes sense, I can open a ticket.
    > 
    >        Aur?lien
    
    My non-LNet-experienced thinking is that the network layer expects the IP addresses to be in big-endian always, and Lustre is supplying them in little-endian?  Maybe they just need a "htons(addr)" before calling for_each_netdev()?
    

Looking a bit more closely at the code, it looks like that's the problem. The IP addr is stored in a __be32 which needs to be converted for Intel platforms (at least). Not sure if ifa_local needs to be converted with ntohl() though. There is probably a more specialized function to convert this field.

Aur?lien    

^ permalink raw reply	[flat|nested] 9+ messages in thread

* [lustre-devel] lnet ip2nets option broken in master?
  2019-05-27  8:48 ` Degremont, Aurelien
  2019-05-27 18:03   ` Andreas Dilger
@ 2019-05-28 13:13   ` James Simmons
  2019-05-28 13:57     ` Degremont, Aurelien
  1 sibling, 1 reply; 9+ messages in thread
From: James Simmons @ 2019-05-28 13:13 UTC (permalink / raw)
  To: lustre-devel


On Mon, 27 May 2019, Degremont, Aurelien wrote:

> Hi Chris,
>
> Thanks for the info!
>
> @James, most of the patches you were waiting for are almost landed (last 
ones are in master-next).
> Do you have a draft of the fix for ip2nets you can push in gerrit 
fortestsonly?

Yes I do but I need the the ko2iblnd fix to land as well. I embedded the
patch if you want to do an early review. This is a rough version but does
have light testing. I have some style changes to be sepatated out but 
haven't got to it yet. I made this patch some time ago. So Neil be gentle 
:-)

diff --git a/lnet/include/lnet/lib-lnet.h b/lnet/include/lnet/lib-lnet.h
index 95c4df1..2eb161e 100644
--- a/lnet/include/lnet/lib-lnet.h
+++ b/lnet/include/lnet/lib-lnet.h
@@ -40,9 +40,7 @@
 /* LNET has 0xeXXX */
 #define CFS_FAIL_PTLRPC_OST_BULK_CB2	0xe000
 
-#ifndef __KERNEL__
-# error This include is only for kernel use.
-#endif
+#include <linux/netdevice.h>
 
 #include <libcfs/libcfs.h>
 #include <lnet/api.h>
@@ -841,6 +839,16 @@ int lnet_acceptor_port(void);
 int lnet_acceptor_start(void);
 void lnet_acceptor_stop(void);
 
+struct lnet_inetdev {
+	unsigned int	li_interfaces;
+	int		li_flags;
+	u32		li_ipaddr[LNET_INTERFACES_NUM];
+	u32		li_netmask[LNET_INTERFACES_NUM];
+	char		li_name[LNET_INTERFACES_NUM][IFNAMSIZ];
+};
+
+int lnet_inet_enumerate(struct lnet_ni *ni, struct lnet_inetdev *ifaces,
+			char *iname, int ifaces_done);
 int lnet_sock_setbuf(struct socket *socket, int txbufsize, int rxbufsize);
 int lnet_sock_getbuf(struct socket *socket, int *txbufsize, int *rxbufsize);
 int lnet_sock_getaddr(struct socket *socket, bool remote, __u32 *ip, int *port);
diff --git a/lnet/klnds/gnilnd/gnilnd_aries.h b/lnet/klnds/gnilnd/gnilnd_aries.h
index d9698b6..431442f 100644
--- a/lnet/klnds/gnilnd/gnilnd_aries.h
+++ b/lnet/klnds/gnilnd/gnilnd_aries.h
@@ -24,7 +24,6 @@
 #ifndef _GNILND_ARIES_H
 #define _GNILND_ARIES_H
 
-/* for lnet_ipif_query */
 #include <lnet/lib-lnet.h>
 
 #ifndef _GNILND_HSS_OPS_H
diff --git a/lnet/klnds/o2iblnd/o2iblnd.c b/lnet/klnds/o2iblnd/o2iblnd.c
index bf71ace..29335ed 100644
--- a/lnet/klnds/o2iblnd/o2iblnd.c
+++ b/lnet/klnds/o2iblnd/o2iblnd.c
@@ -2887,80 +2887,6 @@ kiblnd_destroy_dev(struct kib_dev *dev)
         LIBCFS_FREE(dev, sizeof(*dev));
 }
 
-static struct kib_dev *
-kiblnd_create_dev(char *ifname)
-{
-	struct net_device *netdev;
-	struct kib_dev *dev = NULL;
-	int flags;
-	int rc;
-
-	rtnl_lock();
-	for_each_netdev(&init_net, netdev) {
-		struct in_device *in_dev;
-
-		if (strcmp(netdev->name, "lo") == 0) /* skip the loopback IF */
-			continue;
-
-		flags = dev_get_flags(netdev);
-		if (!(flags & IFF_UP)) {
-			CERROR("Can't query IPoIB interface %s: it's down\n",
-			       netdev->name);
-			goto unlock;
-		}
-
-		in_dev = __in_dev_get_rtnl(netdev);
-		if (!in_dev) {
-			CWARN("Interface %s has no IPv4 status.\n",
-			      netdev->name);
-			goto unlock;
-		}
-
-		for_ifa(in_dev)
-			if (strcmp(ifname, ifa->ifa_label) == 0) {
-				LIBCFS_ALLOC(dev, sizeof(*dev));
-				if (!dev)
-					goto unlock;
-
-				dev->ibd_can_failover = !!(flags & IFF_MASTER);
-				dev->ibd_ifip = ntohl(ifa->ifa_local);
-
-				INIT_LIST_HEAD(&dev->ibd_nets);
-				INIT_LIST_HEAD(&dev->ibd_list); /* not yet in kib_devs */
-				INIT_LIST_HEAD(&dev->ibd_fail_list);
-				break;
-			}
-		endfor_ifa(in_dev);
-	}
-	rtnl_unlock();
-
-	if (!dev) {
-		CERROR("Can't find any usable interfaces\n");
-		return NULL;
-	}
-
-	if (dev->ibd_ifip == 0) {
-		CERROR("Can't initialize device: no IP address\n");
-		goto free_dev;
-	}
-	strcpy(&dev->ibd_ifname[0], ifname);
-
-	/* initialize the device */
-	rc = kiblnd_dev_failover(dev);
-	if (rc != 0) {
-		CERROR("Can't initialize device: %d\n", rc);
-		goto free_dev;
-	}
-
-	list_add_tail(&dev->ibd_list, &kiblnd_data.kib_devs);
-	return dev;
-unlock:
-	rtnl_unlock();
-free_dev:
-	LIBCFS_FREE(dev, sizeof(*dev));
-	return NULL;
-}
-
 static void
 kiblnd_base_shutdown(void)
 {
@@ -3241,8 +3167,7 @@ kiblnd_start_schedulers(struct kib_sched_info *sched)
 	return rc;
 }
 
-static int
-kiblnd_dev_start_threads(struct kib_dev *dev, int newdev, u32 *cpts, int ncpts)
+static int kiblnd_dev_start_threads(struct kib_dev *dev, u32 *cpts, int ncpts)
 {
 	int	cpt;
 	int	rc;
@@ -3254,7 +3179,7 @@ kiblnd_dev_start_threads(struct kib_dev *dev, int newdev, u32 *cpts, int ncpts)
 		cpt = (cpts == NULL) ? i : cpts[i];
 		sched = kiblnd_data.kib_scheds[cpt];
 
-		if (!newdev && sched->ibs_nthreads > 0)
+		if (sched->ibs_nthreads > 0)
 			continue;
 
 		rc = kiblnd_start_schedulers(kiblnd_data.kib_scheds[cpt]);
@@ -3267,49 +3192,15 @@ kiblnd_dev_start_threads(struct kib_dev *dev, int newdev, u32 *cpts, int ncpts)
 	return 0;
 }
 
-static struct kib_dev *
-kiblnd_dev_search(char *ifname)
-{
-	struct kib_dev *alias = NULL;
-	struct kib_dev *dev;
-	char		*colon;
-	char		*colon2;
-
-	colon = strchr(ifname, ':');
-	list_for_each_entry(dev, &kiblnd_data.kib_devs, ibd_list) {
-		if (strcmp(&dev->ibd_ifname[0], ifname) == 0)
-			return dev;
-
-		if (alias != NULL)
-			continue;
-
-		colon2 = strchr(dev->ibd_ifname, ':');
-		if (colon != NULL)
-			*colon = 0;
-		if (colon2 != NULL)
-			*colon2 = 0;
-
-		if (strcmp(&dev->ibd_ifname[0], ifname) == 0)
-			alias = dev;
-
-		if (colon != NULL)
-			*colon = ':';
-		if (colon2 != NULL)
-			*colon2 = ':';
-	}
-	return alias;
-}
-
 static int
 kiblnd_startup(struct lnet_ni *ni)
 {
-        char                     *ifname;
 	struct kib_dev *ibdev = NULL;
+	struct lnet_inetdev ifaces;
 	struct kib_net *net;
         unsigned long             flags;
         int                       rc;
-	int			  newdev;
-	int			  node_id;
+	int i;
 
         LASSERT (ni->ni_net->net_lnd == &the_o2iblnd);
 
@@ -3333,43 +3224,65 @@ kiblnd_startup(struct lnet_ni *ni)
 	 * tcp bonding for ksocklnd. Multi-Rail wants each secondary
 	 * IP to be treated as an unique 'struct ni' interfaces instead.
 	 */
-	if (ni->ni_interfaces[0] != NULL) {
-		/* Use the IPoIB interface specified in 'networks=' */
-
-		CLASSERT(LNET_INTERFACES_NUM > 1);
-		if (ni->ni_interfaces[1] != NULL) {
-			CERROR("Multiple interfaces not supported\n");
+	ifaces.li_interfaces = 0;
+	if (!ni->ni_interfaces[0]) {
+		rc = lnet_inet_enumerate(ni, &ifaces, NULL, 0);
+		if (rc < 0)
 			goto failed;
-		}
-
-		ifname = ni->ni_interfaces[0];
 	} else {
-		ifname = *kiblnd_tunables.kib_default_ipif;
+		for (i = 0; i < LNET_INTERFACES_NUM; i++) {
+			int j;
+
+			if (!ni->ni_interfaces[i])
+				break;
+
+			for (j = 0; j < LNET_INTERFACES_NUM; j++) {
+				if (strlen(ifaces.li_name[j]) &&
+				    !strcmp(ifaces.li_name[j],
+					    ni->ni_interfaces[i])) {
+					CERROR("found duplicate %s\n",
+					       ni->ni_interfaces[i]);
+					rc = -EEXIST;
+					goto failed;
+				}
+			}
+
+			rc = lnet_inet_enumerate(ni, &ifaces,
+						 ni->ni_interfaces[i], 0);
+			if (rc < 0)
+				goto failed;
+		}
 	}
 
-        if (strlen(ifname) >= sizeof(ibdev->ibd_ifname)) {
-                CERROR("IPoIB interface name too long: %s\n", ifname);
-                goto failed;
-        }
+	for (i = 0; i < ifaces.li_interfaces; i++) {
+		LIBCFS_ALLOC(ibdev, sizeof(*ibdev));
+		if (!ibdev)
+			goto failed;
 
-	ibdev = kiblnd_dev_search(ifname);
+		ibdev->ibd_ifip = ifaces.li_ipaddr[i];
+		ibdev->ibd_can_failover = !!(ifaces.li_flags & IFF_MASTER);
+		strlcpy(ibdev->ibd_ifname, ifaces.li_name[i],
+			sizeof(ibdev->ibd_ifname));
 
-	newdev = ibdev == NULL;
-	/* hmm...create kib_dev even for alias */
-	if (ibdev == NULL || strcmp(&ibdev->ibd_ifname[0], ifname) != 0)
-		ibdev = kiblnd_create_dev(ifname);
+		INIT_LIST_HEAD(&ibdev->ibd_nets);
+		INIT_LIST_HEAD(&ibdev->ibd_list); /* not yet in kib_devs */
+		INIT_LIST_HEAD(&ibdev->ibd_fail_list);
 
-	if (ibdev == NULL)
-		goto failed;
+		/* initialize the device */
+		rc = kiblnd_dev_failover(ibdev);
+		if (rc) {
+			CERROR("Can't initialize device: %d\n", rc);
+			LIBCFS_FREE(ibdev, sizeof(*ibdev));
+			goto failed;
+		}
 
-	node_id = dev_to_node(ibdev->ibd_hdev->ibh_ibdev->dma_device);
-	ni->ni_dev_cpt = cfs_cpt_of_node(lnet_cpt_table(), node_id);
+		list_add_tail(&ibdev->ibd_list, &kiblnd_data.kib_devs);
+	}
 
 	net->ibn_dev = ibdev;
 	ni->ni_nid = LNET_MKNID(LNET_NIDNET(ni->ni_nid), ibdev->ibd_ifip);
 
-	rc = kiblnd_dev_start_threads(ibdev, newdev,
-				      ni->ni_cpts, ni->ni_ncpts);
+	rc = kiblnd_dev_start_threads(ibdev, ni->ni_cpts, ni->ni_ncpts);
 	if (rc != 0)
 		goto failed;
 
diff --git a/lnet/klnds/socklnd/socklnd.c b/lnet/klnds/socklnd/socklnd.c
index 9cabeec..1657413 100644
--- a/lnet/klnds/socklnd/socklnd.c
+++ b/lnet/klnds/socklnd/socklnd.c
@@ -2571,62 +2571,6 @@ ksocknal_shutdown(struct lnet_ni *ni)
 }
 
 static int
-ksocknal_enumerate_interfaces(struct ksock_net *net, char *iname)
-{
-	struct net_device *dev;
-
-	rtnl_lock();
-	for_each_netdev(&init_net, dev) {
-		/* The iname specified by an user land configuration can
-		 * map to an ifa_label so always treat iname as an ifa_label.
-		 * If iname is NULL then fall back to the net device name.
-		 */
-		const char *name = iname ? iname : dev->name;
-		struct in_device *in_dev;
-
-		if (strcmp(dev->name, "lo") == 0) /* skip the loopback IF */
-			continue;
-
-		if (!(dev_get_flags(dev) & IFF_UP)) {
-			CWARN("Ignoring interface %s (down)\n", dev->name);
-			continue;
-		}
-
-		in_dev = __in_dev_get_rtnl(dev);
-		if (!in_dev) {
-			CWARN("Interface %s has no IPv4 status.\n", dev->name);
-			continue;
-		}
-
-		for_ifa(in_dev)
-			if (strcmp(name, ifa->ifa_label) == 0) {
-				int idx = net->ksnn_ninterfaces;
-				struct ksock_interface *ksi;
-
-				if (idx >= ARRAY_SIZE(net->ksnn_interfaces)) {
-					rtnl_unlock();
-					return -E2BIG;
-				}
-
-				ksi = &net->ksnn_interfaces[idx];
-				ksi->ksni_ipaddr = ntohl(ifa->ifa_local);
-				ksi->ksni_netmask = ifa->ifa_mask;
-				strlcpy(ksi->ksni_name,
-					name, sizeof(ksi->ksni_name));
-				net->ksnn_ninterfaces++;
-				break;
-			}
-		endfor_ifa(in_dev);
-        }
-	rtnl_unlock();
-
-	if (net->ksnn_ninterfaces == 0)
-                CERROR("Can't find any usable interfaces\n");
-
-	return net->ksnn_ninterfaces > 0 ? 0 : -ENOENT;
-}
-
-static int
 ksocknal_search_new_ipif(struct ksock_net *net)
 {
 	int new_ipif = 0;
@@ -2743,12 +2687,11 @@ ksocknal_net_start_threads(struct ksock_net *net, __u32 *cpts, int ncpts)
 int
 ksocknal_startup(struct lnet_ni *ni)
 {
-	struct ksock_net *net;
 	struct lnet_ioctl_config_lnd_cmn_tunables *net_tunables;
+	struct lnet_inetdev ifaces;
+	struct ksock_net *net;
 	int rc;
 	int i;
-	struct net_device *net_dev;
-	int node_id;
 
         LASSERT (ni->ni_net->net_lnd == &the_ksocklnd);
 
@@ -2788,8 +2731,9 @@ ksocknal_startup(struct lnet_ni *ni)
 		net_tunables->lct_peer_rtr_credits =
 			*ksocknal_tunables.ksnd_peerrtrcredits;
 
+	ifaces.li_interfaces = 0;
 	if (!ni->ni_interfaces[0]) {
-		rc = ksocknal_enumerate_interfaces(net, NULL);
+		rc = lnet_inet_enumerate(ni, &ifaces, NULL, 0);
 		if (rc < 0)
 			goto fail_1;
 	} else {
@@ -2809,34 +2753,32 @@ ksocknal_startup(struct lnet_ni *ni)
 			if (!ni->ni_interfaces[i])
 				break;
 
-			for (j = 0; j < net->ksnn_ninterfaces;  j++) {
-				struct ksock_interface *ksi;
-
-				ksi = &net->ksnn_interfaces[j];
-
-				if (strcmp(ni->ni_interfaces[i],
-					   ksi->ksni_name) == 0) {
+			for (j = 0; j < LNET_INTERFACES_NUM;  j++) {
+				if (strcmp(ifaces.li_name[j],
+					   ni->ni_interfaces[i]) == 0) {
 					CERROR("found duplicate %s\n",
-					       ksi->ksni_name);
+					       ni->ni_interfaces[i]);
 					rc = -EEXIST;
 					goto fail_1;
 				}
 			}
 
-			rc = ksocknal_enumerate_interfaces(net, ni->ni_interfaces[i]);
+			rc = lnet_inet_enumerate(ni, &ifaces,
+						 ni->ni_interfaces[i], 0);
 			if (rc < 0)
 				goto fail_1;
 		}
 	}
 
-	net_dev = dev_get_by_name(&init_net,
-				  net->ksnn_interfaces[0].ksni_name);
-	if (net_dev != NULL) {
-		node_id = dev_to_node(&net_dev->dev);
-		ni->ni_dev_cpt = cfs_cpt_of_node(lnet_cpt_table(), node_id);
-		dev_put(net_dev);
-	} else {
-		ni->ni_dev_cpt = CFS_CPT_ANY;
+	net->ksnn_ninterfaces = ifaces.li_interfaces;
+	for (i = 0; i < net->ksnn_ninterfaces; i++) {
+		struct ksock_interface *ksi;
+
+		ksi = &net->ksnn_interfaces[i];
+		ksi->ksni_ipaddr = ifaces.li_ipaddr[i];
+		ksi->ksni_netmask = ifaces.li_netmask[i];
+		strlcpy(ksi->ksni_name, ifaces.li_name[i],
+			sizeof(ksi->ksni_name));
 	}
 
 	/* call it before add it to ksocknal_data.ksnd_nets */
diff --git a/lnet/lnet/config.c b/lnet/lnet/config.c
index 12b2442..666f0f0 100644
--- a/lnet/lnet/config.c
+++ b/lnet/lnet/config.c
@@ -1611,34 +1611,28 @@ lnet_match_networks (char **networksp, char *ip2nets, __u32 *ipaddrs, int nip)
 	return count;
 }
 
-static void
-lnet_ipaddr_free_enumeration(__u32 *ipaddrs, int nip)
-{
-	LIBCFS_FREE(ipaddrs, nip * sizeof(*ipaddrs));
-}
-
-static int
-lnet_ipaddr_enumerate(u32 **ipaddrsp)
+int lnet_inet_enumerate(struct lnet_ni *ni, struct lnet_inetdev *ifaces,
+			char *iname, int ifa_done)
 {
 	struct net_device *dev;
-	u32 *ipaddrs;
-	int nalloc = 64;
-	int nip = 0;
-
-	LIBCFS_ALLOC(ipaddrs, nalloc * sizeof(*ipaddrs));
-	if (!ipaddrs) {
-		CERROR("Can't allocate ipaddrs[%d]\n", nalloc);
-		return -ENOMEM;
-	}
+	int skip = 0;
+	int rc = 0;
 
 	rtnl_lock();
 	for_each_netdev(&init_net, dev) {
+		/* The iname specified by an user land configuration can
+		 * map to an ifa_label so always treat iname as an ifa_label.
+		 * If iname is NULL then fall back to the net device name.
+		 */
+		const char *name = iname ? iname : dev->name;
 		struct in_device *in_dev;
 
-		if (strcmp(dev->name, "lo") == 0)
+		ifaces->li_flags = dev_get_flags(dev);
+
+		if (ifaces->li_flags & IFF_LOOPBACK) /* skip the loopback IF */
 			continue;
 
-		if (!(dev_get_flags(dev) & IFF_UP)) {
+		if (!(ifaces->li_flags & IFF_UP)) {
 			CWARN("Ignoring interface %s: it's down\n", dev->name);
 			continue;
 		}
@@ -1649,65 +1643,109 @@ lnet_ipaddr_enumerate(u32 **ipaddrsp)
 			continue;
 		}
 
-		if (nip >= nalloc) {
-			u32 *ipaddrs2;
+		if (ni && ni->ni_dev_cpt != CFS_CPT_ANY) {
+			int node_id = dev_to_node(&dev->dev);
+			int cpt = cfs_cpt_of_node(lnet_cpt_table(), node_id);
 
-			nalloc += nalloc;
-			ipaddrs2 = krealloc(ipaddrs, nalloc * sizeof(*ipaddrs2),
-					    GFP_KERNEL);
-			if (!ipaddrs2) {
-				kfree(ipaddrs);
-				CERROR("Can't allocate ipaddrs[%d]\n", nip);
-				return -ENOMEM;
+			if (ni->ni_dev_cpt != cpt &&
+			    ifaces->li_interfaces > 0) {
+				ni->ni_dev_cpt = CFS_CPT_ANY;
+				CWARN("Not all the network interfaces belong to the same CPT\n");
+			} else {
+				ni->ni_dev_cpt = cpt;
 			}
-			ipaddrs = ipaddrs2;
 		}
 
-		for_primary_ifa(in_dev)
-			if (strcmp(ifa->ifa_label, dev->name) == 0) {
-				ipaddrs[nip++] = ifa->ifa_local;
-				break;
+		for_ifa(in_dev)
+			if (strcmp(name, ifa->ifa_label) == 0) {
+				int idx = ifaces->li_interfaces;
+
+				if (idx >= ARRAY_SIZE(ifaces->li_name))
+					return -E2BIG;
+
+				if (skip++ < ifa_done)
+					continue;
+
+				ifaces->li_ipaddr[idx] = ntohl(ifa->ifa_local);
+				ifaces->li_netmask[idx] = ifa->ifa_mask;
+				strlcpy(ifaces->li_name[idx], name,
+					sizeof(ifaces->li_name[idx]));
+				ifaces->li_interfaces++;
+				goto unlock_rtnl;
 			}
 		endfor_ifa(in_dev);
 	}
+unlock_rtnl:
 	rtnl_unlock();
 
-	*ipaddrsp = ipaddrs;
-	return nip;
+	if (ifaces->li_interfaces == 0) {
+		CERROR("Can't find any usable interfaces\n");
+		rc = -ENOENT;
+	}
+
+	return rc;
 }
+EXPORT_SYMBOL(lnet_inet_enumerate);
 
 int
-lnet_parse_ip2nets (char **networksp, char *ip2nets)
+lnet_parse_ip2nets(char **networksp, char *ip2nets)
 {
-	__u32	  *ipaddrs = NULL;
-	int	   nip = lnet_ipaddr_enumerate(&ipaddrs);
-	int	   rc;
-
-	if (nip < 0) {
-		LCONSOLE_ERROR_MSG(0x117, "Error %d enumerating local IP "
-				   "interfaces for ip2nets to match\n", nip);
-		return nip;
-	}
+	struct lnet_inetdev ifaces;
+	u32 *ipaddrs = NULL;
+	int nalloc = 0;
+	int nip = 0;
+	int rc;
 
-	if (nip == 0) {
-		LCONSOLE_ERROR_MSG(0x118, "No local IP interfaces "
-				   "for ip2nets to match\n");
-		return -ENOENT;
-	}
+realloc:
+	ifaces.li_interfaces = 0;
+	rc = lnet_inet_enumerate(NULL, &ifaces, NULL, nip);
+	if (rc < 0) {
+		/* Handle edge case where we nip is muliple of
+		 * LNET_INTERFACES_NUM and no more devices are
+		 * detected.
+		 */
+		if (rc == -ENOENT && nip > 0)
+			goto match_networks;
 
-	rc = lnet_match_networks(networksp, ip2nets, ipaddrs, nip);
-	lnet_ipaddr_free_enumeration(ipaddrs, nip);
+		LCONSOLE_ERROR_MSG(0x117,
+				   "Error %d enumerating local IP interfaces for ip2nets to match\n",
+				   rc);
+		goto out_free_addrs;
+	} else {
+		u32 *ipaddrs2;
+		int i;
+
+		nalloc += ifaces.li_interfaces;
+		ipaddrs2 = krealloc(ipaddrs, nalloc * sizeof(*ipaddrs),
+				    GFP_KERNEL);
+		if (!ipaddrs2) {
+			CERROR("Can't allocate ipaddrs[%d]\n", nalloc);
+			goto out_free_addrs;
+		}
+		ipaddrs = ipaddrs2;
 
+		for (i = 0; i < ifaces.li_interfaces; i++) {
+			memcpy(ipaddrs + nip, ifaces.li_ipaddr,
+			       sizeof(*ipaddrs) * LNET_INTERFACES_NUM);
+		}
+
+		/* Maybe more ? */
+		if (ifaces.li_interfaces == LNET_INTERFACES_NUM) {
+			nip += LNET_INTERFACES_NUM;
+			goto realloc;
+		}
+	}
+match_networks:
+	rc = lnet_match_networks(networksp, ip2nets, ipaddrs, nip);
 	if (rc < 0) {
 		LCONSOLE_ERROR_MSG(0x119, "Error %d parsing ip2nets\n", rc);
 		return rc;
-	}
-
-	if (rc == 0) {
+	} else if (rc == 0) {
 		LCONSOLE_ERROR_MSG(0x11a, "ip2nets does not match "
 				   "any local IP interfaces\n");
 		return -ENOENT;
 	}
-
-	return 0;
+out_free_addrs:
+	LIBCFS_FREE(ipaddrs, nip * sizeof(*ipaddrs));
+	return rc;
 }
-- 
1.8.3.1

^ permalink raw reply related	[flat|nested] 9+ messages in thread

* [lustre-devel] lnet ip2nets option broken in master?
  2019-05-28 13:13   ` James Simmons
@ 2019-05-28 13:57     ` Degremont, Aurelien
  2019-06-11  6:27       ` Andreas Dilger
  0 siblings, 1 reply; 9+ messages in thread
From: Degremont, Aurelien @ 2019-05-28 13:57 UTC (permalink / raw)
  To: lustre-devel

Oh, I was thinking of a smaller change.
This patch looks like (good) code refactoring.

It seems the fix for ip2nets in master is indeed just a "ntohl(ifa->ifa_local);" for lnet_ipaddr_enumerate()


Aur?lien

?Le 28/05/2019 15:13, ? James Simmons ? <jsimmons@infradead.org> a ?crit :

    
    On Mon, 27 May 2019, Degremont, Aurelien wrote:
    
    > Hi Chris,
    >
    > Thanks for the info!
    >
    > @James, most of the patches you were waiting for are almost landed (last 
    ones are in master-next).
    > Do you have a draft of the fix for ip2nets you can push in gerrit 
    fortestsonly?
    
    Yes I do but I need the the ko2iblnd fix to land as well. I embedded the
    patch if you want to do an early review. This is a rough version but does
    have light testing. I have some style changes to be sepatated out but 
    haven't got to it yet. I made this patch some time ago. So Neil be gentle 
    :-)
    
    diff --git a/lnet/include/lnet/lib-lnet.h b/lnet/include/lnet/lib-lnet.h
    index 95c4df1..2eb161e 100644
    --- a/lnet/include/lnet/lib-lnet.h
    +++ b/lnet/include/lnet/lib-lnet.h
    @@ -40,9 +40,7 @@
     /* LNET has 0xeXXX */
     #define CFS_FAIL_PTLRPC_OST_BULK_CB2	0xe000
     
    -#ifndef __KERNEL__
    -# error This include is only for kernel use.
    -#endif
    +#include <linux/netdevice.h>
     
     #include <libcfs/libcfs.h>
     #include <lnet/api.h>
    @@ -841,6 +839,16 @@ int lnet_acceptor_port(void);
     int lnet_acceptor_start(void);
     void lnet_acceptor_stop(void);
     
    +struct lnet_inetdev {
    +	unsigned int	li_interfaces;
    +	int		li_flags;
    +	u32		li_ipaddr[LNET_INTERFACES_NUM];
    +	u32		li_netmask[LNET_INTERFACES_NUM];
    +	char		li_name[LNET_INTERFACES_NUM][IFNAMSIZ];
    +};
    +
    +int lnet_inet_enumerate(struct lnet_ni *ni, struct lnet_inetdev *ifaces,
    +			char *iname, int ifaces_done);
     int lnet_sock_setbuf(struct socket *socket, int txbufsize, int rxbufsize);
     int lnet_sock_getbuf(struct socket *socket, int *txbufsize, int *rxbufsize);
     int lnet_sock_getaddr(struct socket *socket, bool remote, __u32 *ip, int *port);
    diff --git a/lnet/klnds/gnilnd/gnilnd_aries.h b/lnet/klnds/gnilnd/gnilnd_aries.h
    index d9698b6..431442f 100644
    --- a/lnet/klnds/gnilnd/gnilnd_aries.h
    +++ b/lnet/klnds/gnilnd/gnilnd_aries.h
    @@ -24,7 +24,6 @@
     #ifndef _GNILND_ARIES_H
     #define _GNILND_ARIES_H
     
    -/* for lnet_ipif_query */
     #include <lnet/lib-lnet.h>
     
     #ifndef _GNILND_HSS_OPS_H
    diff --git a/lnet/klnds/o2iblnd/o2iblnd.c b/lnet/klnds/o2iblnd/o2iblnd.c
    index bf71ace..29335ed 100644
    --- a/lnet/klnds/o2iblnd/o2iblnd.c
    +++ b/lnet/klnds/o2iblnd/o2iblnd.c
    @@ -2887,80 +2887,6 @@ kiblnd_destroy_dev(struct kib_dev *dev)
             LIBCFS_FREE(dev, sizeof(*dev));
     }
     
    -static struct kib_dev *
    -kiblnd_create_dev(char *ifname)
    -{
    -	struct net_device *netdev;
    -	struct kib_dev *dev = NULL;
    -	int flags;
    -	int rc;
    -
    -	rtnl_lock();
    -	for_each_netdev(&init_net, netdev) {
    -		struct in_device *in_dev;
    -
    -		if (strcmp(netdev->name, "lo") == 0) /* skip the loopback IF */
    -			continue;
    -
    -		flags = dev_get_flags(netdev);
    -		if (!(flags & IFF_UP)) {
    -			CERROR("Can't query IPoIB interface %s: it's down\n",
    -			       netdev->name);
    -			goto unlock;
    -		}
    -
    -		in_dev = __in_dev_get_rtnl(netdev);
    -		if (!in_dev) {
    -			CWARN("Interface %s has no IPv4 status.\n",
    -			      netdev->name);
    -			goto unlock;
    -		}
    -
    -		for_ifa(in_dev)
    -			if (strcmp(ifname, ifa->ifa_label) == 0) {
    -				LIBCFS_ALLOC(dev, sizeof(*dev));
    -				if (!dev)
    -					goto unlock;
    -
    -				dev->ibd_can_failover = !!(flags & IFF_MASTER);
    -				dev->ibd_ifip = ntohl(ifa->ifa_local);
    -
    -				INIT_LIST_HEAD(&dev->ibd_nets);
    -				INIT_LIST_HEAD(&dev->ibd_list); /* not yet in kib_devs */
    -				INIT_LIST_HEAD(&dev->ibd_fail_list);
    -				break;
    -			}
    -		endfor_ifa(in_dev);
    -	}
    -	rtnl_unlock();
    -
    -	if (!dev) {
    -		CERROR("Can't find any usable interfaces\n");
    -		return NULL;
    -	}
    -
    -	if (dev->ibd_ifip == 0) {
    -		CERROR("Can't initialize device: no IP address\n");
    -		goto free_dev;
    -	}
    -	strcpy(&dev->ibd_ifname[0], ifname);
    -
    -	/* initialize the device */
    -	rc = kiblnd_dev_failover(dev);
    -	if (rc != 0) {
    -		CERROR("Can't initialize device: %d\n", rc);
    -		goto free_dev;
    -	}
    -
    -	list_add_tail(&dev->ibd_list, &kiblnd_data.kib_devs);
    -	return dev;
    -unlock:
    -	rtnl_unlock();
    -free_dev:
    -	LIBCFS_FREE(dev, sizeof(*dev));
    -	return NULL;
    -}
    -
     static void
     kiblnd_base_shutdown(void)
     {
    @@ -3241,8 +3167,7 @@ kiblnd_start_schedulers(struct kib_sched_info *sched)
     	return rc;
     }
     
    -static int
    -kiblnd_dev_start_threads(struct kib_dev *dev, int newdev, u32 *cpts, int ncpts)
    +static int kiblnd_dev_start_threads(struct kib_dev *dev, u32 *cpts, int ncpts)
     {
     	int	cpt;
     	int	rc;
    @@ -3254,7 +3179,7 @@ kiblnd_dev_start_threads(struct kib_dev *dev, int newdev, u32 *cpts, int ncpts)
     		cpt = (cpts == NULL) ? i : cpts[i];
     		sched = kiblnd_data.kib_scheds[cpt];
     
    -		if (!newdev && sched->ibs_nthreads > 0)
    +		if (sched->ibs_nthreads > 0)
     			continue;
     
     		rc = kiblnd_start_schedulers(kiblnd_data.kib_scheds[cpt]);
    @@ -3267,49 +3192,15 @@ kiblnd_dev_start_threads(struct kib_dev *dev, int newdev, u32 *cpts, int ncpts)
     	return 0;
     }
     
    -static struct kib_dev *
    -kiblnd_dev_search(char *ifname)
    -{
    -	struct kib_dev *alias = NULL;
    -	struct kib_dev *dev;
    -	char		*colon;
    -	char		*colon2;
    -
    -	colon = strchr(ifname, ':');
    -	list_for_each_entry(dev, &kiblnd_data.kib_devs, ibd_list) {
    -		if (strcmp(&dev->ibd_ifname[0], ifname) == 0)
    -			return dev;
    -
    -		if (alias != NULL)
    -			continue;
    -
    -		colon2 = strchr(dev->ibd_ifname, ':');
    -		if (colon != NULL)
    -			*colon = 0;
    -		if (colon2 != NULL)
    -			*colon2 = 0;
    -
    -		if (strcmp(&dev->ibd_ifname[0], ifname) == 0)
    -			alias = dev;
    -
    -		if (colon != NULL)
    -			*colon = ':';
    -		if (colon2 != NULL)
    -			*colon2 = ':';
    -	}
    -	return alias;
    -}
    -
     static int
     kiblnd_startup(struct lnet_ni *ni)
     {
    -        char                     *ifname;
     	struct kib_dev *ibdev = NULL;
    +	struct lnet_inetdev ifaces;
     	struct kib_net *net;
             unsigned long             flags;
             int                       rc;
    -	int			  newdev;
    -	int			  node_id;
    +	int i;
     
             LASSERT (ni->ni_net->net_lnd == &the_o2iblnd);
     
    @@ -3333,43 +3224,65 @@ kiblnd_startup(struct lnet_ni *ni)
     	 * tcp bonding for ksocklnd. Multi-Rail wants each secondary
     	 * IP to be treated as an unique 'struct ni' interfaces instead.
     	 */
    -	if (ni->ni_interfaces[0] != NULL) {
    -		/* Use the IPoIB interface specified in 'networks=' */
    -
    -		CLASSERT(LNET_INTERFACES_NUM > 1);
    -		if (ni->ni_interfaces[1] != NULL) {
    -			CERROR("Multiple interfaces not supported\n");
    +	ifaces.li_interfaces = 0;
    +	if (!ni->ni_interfaces[0]) {
    +		rc = lnet_inet_enumerate(ni, &ifaces, NULL, 0);
    +		if (rc < 0)
     			goto failed;
    -		}
    -
    -		ifname = ni->ni_interfaces[0];
     	} else {
    -		ifname = *kiblnd_tunables.kib_default_ipif;
    +		for (i = 0; i < LNET_INTERFACES_NUM; i++) {
    +			int j;
    +
    +			if (!ni->ni_interfaces[i])
    +				break;
    +
    +			for (j = 0; j < LNET_INTERFACES_NUM; j++) {
    +				if (strlen(ifaces.li_name[j]) &&
    +				    !strcmp(ifaces.li_name[j],
    +					    ni->ni_interfaces[i])) {
    +					CERROR("found duplicate %s\n",
    +					       ni->ni_interfaces[i]);
    +					rc = -EEXIST;
    +					goto failed;
    +				}
    +			}
    +
    +			rc = lnet_inet_enumerate(ni, &ifaces,
    +						 ni->ni_interfaces[i], 0);
    +			if (rc < 0)
    +				goto failed;
    +		}
     	}
     
    -        if (strlen(ifname) >= sizeof(ibdev->ibd_ifname)) {
    -                CERROR("IPoIB interface name too long: %s\n", ifname);
    -                goto failed;
    -        }
    +	for (i = 0; i < ifaces.li_interfaces; i++) {
    +		LIBCFS_ALLOC(ibdev, sizeof(*ibdev));
    +		if (!ibdev)
    +			goto failed;
     
    -	ibdev = kiblnd_dev_search(ifname);
    +		ibdev->ibd_ifip = ifaces.li_ipaddr[i];
    +		ibdev->ibd_can_failover = !!(ifaces.li_flags & IFF_MASTER);
    +		strlcpy(ibdev->ibd_ifname, ifaces.li_name[i],
    +			sizeof(ibdev->ibd_ifname));
     
    -	newdev = ibdev == NULL;
    -	/* hmm...create kib_dev even for alias */
    -	if (ibdev == NULL || strcmp(&ibdev->ibd_ifname[0], ifname) != 0)
    -		ibdev = kiblnd_create_dev(ifname);
    +		INIT_LIST_HEAD(&ibdev->ibd_nets);
    +		INIT_LIST_HEAD(&ibdev->ibd_list); /* not yet in kib_devs */
    +		INIT_LIST_HEAD(&ibdev->ibd_fail_list);
     
    -	if (ibdev == NULL)
    -		goto failed;
    +		/* initialize the device */
    +		rc = kiblnd_dev_failover(ibdev);
    +		if (rc) {
    +			CERROR("Can't initialize device: %d\n", rc);
    +			LIBCFS_FREE(ibdev, sizeof(*ibdev));
    +			goto failed;
    +		}
     
    -	node_id = dev_to_node(ibdev->ibd_hdev->ibh_ibdev->dma_device);
    -	ni->ni_dev_cpt = cfs_cpt_of_node(lnet_cpt_table(), node_id);
    +		list_add_tail(&ibdev->ibd_list, &kiblnd_data.kib_devs);
    +	}
     
     	net->ibn_dev = ibdev;
     	ni->ni_nid = LNET_MKNID(LNET_NIDNET(ni->ni_nid), ibdev->ibd_ifip);
     
    -	rc = kiblnd_dev_start_threads(ibdev, newdev,
    -				      ni->ni_cpts, ni->ni_ncpts);
    +	rc = kiblnd_dev_start_threads(ibdev, ni->ni_cpts, ni->ni_ncpts);
     	if (rc != 0)
     		goto failed;
     
    diff --git a/lnet/klnds/socklnd/socklnd.c b/lnet/klnds/socklnd/socklnd.c
    index 9cabeec..1657413 100644
    --- a/lnet/klnds/socklnd/socklnd.c
    +++ b/lnet/klnds/socklnd/socklnd.c
    @@ -2571,62 +2571,6 @@ ksocknal_shutdown(struct lnet_ni *ni)
     }
     
     static int
    -ksocknal_enumerate_interfaces(struct ksock_net *net, char *iname)
    -{
    -	struct net_device *dev;
    -
    -	rtnl_lock();
    -	for_each_netdev(&init_net, dev) {
    -		/* The iname specified by an user land configuration can
    -		 * map to an ifa_label so always treat iname as an ifa_label.
    -		 * If iname is NULL then fall back to the net device name.
    -		 */
    -		const char *name = iname ? iname : dev->name;
    -		struct in_device *in_dev;
    -
    -		if (strcmp(dev->name, "lo") == 0) /* skip the loopback IF */
    -			continue;
    -
    -		if (!(dev_get_flags(dev) & IFF_UP)) {
    -			CWARN("Ignoring interface %s (down)\n", dev->name);
    -			continue;
    -		}
    -
    -		in_dev = __in_dev_get_rtnl(dev);
    -		if (!in_dev) {
    -			CWARN("Interface %s has no IPv4 status.\n", dev->name);
    -			continue;
    -		}
    -
    -		for_ifa(in_dev)
    -			if (strcmp(name, ifa->ifa_label) == 0) {
    -				int idx = net->ksnn_ninterfaces;
    -				struct ksock_interface *ksi;
    -
    -				if (idx >= ARRAY_SIZE(net->ksnn_interfaces)) {
    -					rtnl_unlock();
    -					return -E2BIG;
    -				}
    -
    -				ksi = &net->ksnn_interfaces[idx];
    -				ksi->ksni_ipaddr = ntohl(ifa->ifa_local);
    -				ksi->ksni_netmask = ifa->ifa_mask;
    -				strlcpy(ksi->ksni_name,
    -					name, sizeof(ksi->ksni_name));
    -				net->ksnn_ninterfaces++;
    -				break;
    -			}
    -		endfor_ifa(in_dev);
    -        }
    -	rtnl_unlock();
    -
    -	if (net->ksnn_ninterfaces == 0)
    -                CERROR("Can't find any usable interfaces\n");
    -
    -	return net->ksnn_ninterfaces > 0 ? 0 : -ENOENT;
    -}
    -
    -static int
     ksocknal_search_new_ipif(struct ksock_net *net)
     {
     	int new_ipif = 0;
    @@ -2743,12 +2687,11 @@ ksocknal_net_start_threads(struct ksock_net *net, __u32 *cpts, int ncpts)
     int
     ksocknal_startup(struct lnet_ni *ni)
     {
    -	struct ksock_net *net;
     	struct lnet_ioctl_config_lnd_cmn_tunables *net_tunables;
    +	struct lnet_inetdev ifaces;
    +	struct ksock_net *net;
     	int rc;
     	int i;
    -	struct net_device *net_dev;
    -	int node_id;
     
             LASSERT (ni->ni_net->net_lnd == &the_ksocklnd);
     
    @@ -2788,8 +2731,9 @@ ksocknal_startup(struct lnet_ni *ni)
     		net_tunables->lct_peer_rtr_credits =
     			*ksocknal_tunables.ksnd_peerrtrcredits;
     
    +	ifaces.li_interfaces = 0;
     	if (!ni->ni_interfaces[0]) {
    -		rc = ksocknal_enumerate_interfaces(net, NULL);
    +		rc = lnet_inet_enumerate(ni, &ifaces, NULL, 0);
     		if (rc < 0)
     			goto fail_1;
     	} else {
    @@ -2809,34 +2753,32 @@ ksocknal_startup(struct lnet_ni *ni)
     			if (!ni->ni_interfaces[i])
     				break;
     
    -			for (j = 0; j < net->ksnn_ninterfaces;  j++) {
    -				struct ksock_interface *ksi;
    -
    -				ksi = &net->ksnn_interfaces[j];
    -
    -				if (strcmp(ni->ni_interfaces[i],
    -					   ksi->ksni_name) == 0) {
    +			for (j = 0; j < LNET_INTERFACES_NUM;  j++) {
    +				if (strcmp(ifaces.li_name[j],
    +					   ni->ni_interfaces[i]) == 0) {
     					CERROR("found duplicate %s\n",
    -					       ksi->ksni_name);
    +					       ni->ni_interfaces[i]);
     					rc = -EEXIST;
     					goto fail_1;
     				}
     			}
     
    -			rc = ksocknal_enumerate_interfaces(net, ni->ni_interfaces[i]);
    +			rc = lnet_inet_enumerate(ni, &ifaces,
    +						 ni->ni_interfaces[i], 0);
     			if (rc < 0)
     				goto fail_1;
     		}
     	}
     
    -	net_dev = dev_get_by_name(&init_net,
    -				  net->ksnn_interfaces[0].ksni_name);
    -	if (net_dev != NULL) {
    -		node_id = dev_to_node(&net_dev->dev);
    -		ni->ni_dev_cpt = cfs_cpt_of_node(lnet_cpt_table(), node_id);
    -		dev_put(net_dev);
    -	} else {
    -		ni->ni_dev_cpt = CFS_CPT_ANY;
    +	net->ksnn_ninterfaces = ifaces.li_interfaces;
    +	for (i = 0; i < net->ksnn_ninterfaces; i++) {
    +		struct ksock_interface *ksi;
    +
    +		ksi = &net->ksnn_interfaces[i];
    +		ksi->ksni_ipaddr = ifaces.li_ipaddr[i];
    +		ksi->ksni_netmask = ifaces.li_netmask[i];
    +		strlcpy(ksi->ksni_name, ifaces.li_name[i],
    +			sizeof(ksi->ksni_name));
     	}
     
     	/* call it before add it to ksocknal_data.ksnd_nets */
    diff --git a/lnet/lnet/config.c b/lnet/lnet/config.c
    index 12b2442..666f0f0 100644
    --- a/lnet/lnet/config.c
    +++ b/lnet/lnet/config.c
    @@ -1611,34 +1611,28 @@ lnet_match_networks (char **networksp, char *ip2nets, __u32 *ipaddrs, int nip)
     	return count;
     }
     
    -static void
    -lnet_ipaddr_free_enumeration(__u32 *ipaddrs, int nip)
    -{
    -	LIBCFS_FREE(ipaddrs, nip * sizeof(*ipaddrs));
    -}
    -
    -static int
    -lnet_ipaddr_enumerate(u32 **ipaddrsp)
    +int lnet_inet_enumerate(struct lnet_ni *ni, struct lnet_inetdev *ifaces,
    +			char *iname, int ifa_done)
     {
     	struct net_device *dev;
    -	u32 *ipaddrs;
    -	int nalloc = 64;
    -	int nip = 0;
    -
    -	LIBCFS_ALLOC(ipaddrs, nalloc * sizeof(*ipaddrs));
    -	if (!ipaddrs) {
    -		CERROR("Can't allocate ipaddrs[%d]\n", nalloc);
    -		return -ENOMEM;
    -	}
    +	int skip = 0;
    +	int rc = 0;
     
     	rtnl_lock();
     	for_each_netdev(&init_net, dev) {
    +		/* The iname specified by an user land configuration can
    +		 * map to an ifa_label so always treat iname as an ifa_label.
    +		 * If iname is NULL then fall back to the net device name.
    +		 */
    +		const char *name = iname ? iname : dev->name;
     		struct in_device *in_dev;
     
    -		if (strcmp(dev->name, "lo") == 0)
    +		ifaces->li_flags = dev_get_flags(dev);
    +
    +		if (ifaces->li_flags & IFF_LOOPBACK) /* skip the loopback IF */
     			continue;
     
    -		if (!(dev_get_flags(dev) & IFF_UP)) {
    +		if (!(ifaces->li_flags & IFF_UP)) {
     			CWARN("Ignoring interface %s: it's down\n", dev->name);
     			continue;
     		}
    @@ -1649,65 +1643,109 @@ lnet_ipaddr_enumerate(u32 **ipaddrsp)
     			continue;
     		}
     
    -		if (nip >= nalloc) {
    -			u32 *ipaddrs2;
    +		if (ni && ni->ni_dev_cpt != CFS_CPT_ANY) {
    +			int node_id = dev_to_node(&dev->dev);
    +			int cpt = cfs_cpt_of_node(lnet_cpt_table(), node_id);
     
    -			nalloc += nalloc;
    -			ipaddrs2 = krealloc(ipaddrs, nalloc * sizeof(*ipaddrs2),
    -					    GFP_KERNEL);
    -			if (!ipaddrs2) {
    -				kfree(ipaddrs);
    -				CERROR("Can't allocate ipaddrs[%d]\n", nip);
    -				return -ENOMEM;
    +			if (ni->ni_dev_cpt != cpt &&
    +			    ifaces->li_interfaces > 0) {
    +				ni->ni_dev_cpt = CFS_CPT_ANY;
    +				CWARN("Not all the network interfaces belong to the same CPT\n");
    +			} else {
    +				ni->ni_dev_cpt = cpt;
     			}
    -			ipaddrs = ipaddrs2;
     		}
     
    -		for_primary_ifa(in_dev)
    -			if (strcmp(ifa->ifa_label, dev->name) == 0) {
    -				ipaddrs[nip++] = ifa->ifa_local;
    -				break;
    +		for_ifa(in_dev)
    +			if (strcmp(name, ifa->ifa_label) == 0) {
    +				int idx = ifaces->li_interfaces;
    +
    +				if (idx >= ARRAY_SIZE(ifaces->li_name))
    +					return -E2BIG;
    +
    +				if (skip++ < ifa_done)
    +					continue;
    +
    +				ifaces->li_ipaddr[idx] = ntohl(ifa->ifa_local);
    +				ifaces->li_netmask[idx] = ifa->ifa_mask;
    +				strlcpy(ifaces->li_name[idx], name,
    +					sizeof(ifaces->li_name[idx]));
    +				ifaces->li_interfaces++;
    +				goto unlock_rtnl;
     			}
     		endfor_ifa(in_dev);
     	}
    +unlock_rtnl:
     	rtnl_unlock();
     
    -	*ipaddrsp = ipaddrs;
    -	return nip;
    +	if (ifaces->li_interfaces == 0) {
    +		CERROR("Can't find any usable interfaces\n");
    +		rc = -ENOENT;
    +	}
    +
    +	return rc;
     }
    +EXPORT_SYMBOL(lnet_inet_enumerate);
     
     int
    -lnet_parse_ip2nets (char **networksp, char *ip2nets)
    +lnet_parse_ip2nets(char **networksp, char *ip2nets)
     {
    -	__u32	  *ipaddrs = NULL;
    -	int	   nip = lnet_ipaddr_enumerate(&ipaddrs);
    -	int	   rc;
    -
    -	if (nip < 0) {
    -		LCONSOLE_ERROR_MSG(0x117, "Error %d enumerating local IP "
    -				   "interfaces for ip2nets to match\n", nip);
    -		return nip;
    -	}
    +	struct lnet_inetdev ifaces;
    +	u32 *ipaddrs = NULL;
    +	int nalloc = 0;
    +	int nip = 0;
    +	int rc;
     
    -	if (nip == 0) {
    -		LCONSOLE_ERROR_MSG(0x118, "No local IP interfaces "
    -				   "for ip2nets to match\n");
    -		return -ENOENT;
    -	}
    +realloc:
    +	ifaces.li_interfaces = 0;
    +	rc = lnet_inet_enumerate(NULL, &ifaces, NULL, nip);
    +	if (rc < 0) {
    +		/* Handle edge case where we nip is muliple of
    +		 * LNET_INTERFACES_NUM and no more devices are
    +		 * detected.
    +		 */
    +		if (rc == -ENOENT && nip > 0)
    +			goto match_networks;
     
    -	rc = lnet_match_networks(networksp, ip2nets, ipaddrs, nip);
    -	lnet_ipaddr_free_enumeration(ipaddrs, nip);
    +		LCONSOLE_ERROR_MSG(0x117,
    +				   "Error %d enumerating local IP interfaces for ip2nets to match\n",
    +				   rc);
    +		goto out_free_addrs;
    +	} else {
    +		u32 *ipaddrs2;
    +		int i;
    +
    +		nalloc += ifaces.li_interfaces;
    +		ipaddrs2 = krealloc(ipaddrs, nalloc * sizeof(*ipaddrs),
    +				    GFP_KERNEL);
    +		if (!ipaddrs2) {
    +			CERROR("Can't allocate ipaddrs[%d]\n", nalloc);
    +			goto out_free_addrs;
    +		}
    +		ipaddrs = ipaddrs2;
     
    +		for (i = 0; i < ifaces.li_interfaces; i++) {
    +			memcpy(ipaddrs + nip, ifaces.li_ipaddr,
    +			       sizeof(*ipaddrs) * LNET_INTERFACES_NUM);
    +		}
    +
    +		/* Maybe more ? */
    +		if (ifaces.li_interfaces == LNET_INTERFACES_NUM) {
    +			nip += LNET_INTERFACES_NUM;
    +			goto realloc;
    +		}
    +	}
    +match_networks:
    +	rc = lnet_match_networks(networksp, ip2nets, ipaddrs, nip);
     	if (rc < 0) {
     		LCONSOLE_ERROR_MSG(0x119, "Error %d parsing ip2nets\n", rc);
     		return rc;
    -	}
    -
    -	if (rc == 0) {
    +	} else if (rc == 0) {
     		LCONSOLE_ERROR_MSG(0x11a, "ip2nets does not match "
     				   "any local IP interfaces\n");
     		return -ENOENT;
     	}
    -
    -	return 0;
    +out_free_addrs:
    +	LIBCFS_FREE(ipaddrs, nip * sizeof(*ipaddrs));
    +	return rc;
     }
    -- 
    1.8.3.1
    
    

^ permalink raw reply	[flat|nested] 9+ messages in thread

* [lustre-devel] lnet ip2nets option broken in master?
  2019-05-28 13:57     ` Degremont, Aurelien
@ 2019-06-11  6:27       ` Andreas Dilger
  2019-06-11  9:02         ` Degremont, Aurelien
  0 siblings, 1 reply; 9+ messages in thread
From: Andreas Dilger @ 2019-06-11  6:27 UTC (permalink / raw)
  To: lustre-devel

Aurelien,
I just saw your reply in my junk folder... :-(

Could you please open an LU ticket, and possibly push a patch with the fix
that is working for you, rather than me guessing what is supposed to be done.

Cheers, Andreas

On May 28, 2019, at 07:57, Degremont, Aurelien <degremoa@amazon.com> wrote:
> 
> Oh, I was thinking of a smaller change.
> This patch looks like (good) code refactoring.
> 
> It seems the fix for ip2nets in master is indeed just a "ntohl(ifa->ifa_local);" for lnet_ipaddr_enumerate()
> 
> 
> Aur?lien
> 
> ?Le 28/05/2019 15:13, ? James Simmons ? <jsimmons@infradead.org> a ?crit :
> 
> 
>    On Mon, 27 May 2019, Degremont, Aurelien wrote:
> 
>> Hi Chris,
>> 
>> Thanks for the info!
>> 
>> @James, most of the patches you were waiting for are almost landed (last 
>    ones are in master-next).
>> Do you have a draft of the fix for ip2nets you can push in gerrit 
>    fortestsonly?
> 
>    Yes I do but I need the the ko2iblnd fix to land as well. I embedded the
>    patch if you want to do an early review. This is a rough version but does
>    have light testing. I have some style changes to be sepatated out but 
>    haven't got to it yet. I made this patch some time ago. So Neil be gentle 
>    :-)
> 
>    diff --git a/lnet/include/lnet/lib-lnet.h b/lnet/include/lnet/lib-lnet.h
>    index 95c4df1..2eb161e 100644
>    --- a/lnet/include/lnet/lib-lnet.h
>    +++ b/lnet/include/lnet/lib-lnet.h
>    @@ -40,9 +40,7 @@
>     /* LNET has 0xeXXX */
>     #define CFS_FAIL_PTLRPC_OST_BULK_CB2	0xe000
> 
>    -#ifndef __KERNEL__
>    -# error This include is only for kernel use.
>    -#endif
>    +#include <linux/netdevice.h>
> 
>     #include <libcfs/libcfs.h>
>     #include <lnet/api.h>
>    @@ -841,6 +839,16 @@ int lnet_acceptor_port(void);
>     int lnet_acceptor_start(void);
>     void lnet_acceptor_stop(void);
> 
>    +struct lnet_inetdev {
>    +	unsigned int	li_interfaces;
>    +	int		li_flags;
>    +	u32		li_ipaddr[LNET_INTERFACES_NUM];
>    +	u32		li_netmask[LNET_INTERFACES_NUM];
>    +	char		li_name[LNET_INTERFACES_NUM][IFNAMSIZ];
>    +};
>    +
>    +int lnet_inet_enumerate(struct lnet_ni *ni, struct lnet_inetdev *ifaces,
>    +			char *iname, int ifaces_done);
>     int lnet_sock_setbuf(struct socket *socket, int txbufsize, int rxbufsize);
>     int lnet_sock_getbuf(struct socket *socket, int *txbufsize, int *rxbufsize);
>     int lnet_sock_getaddr(struct socket *socket, bool remote, __u32 *ip, int *port);
>    diff --git a/lnet/klnds/gnilnd/gnilnd_aries.h b/lnet/klnds/gnilnd/gnilnd_aries.h
>    index d9698b6..431442f 100644
>    --- a/lnet/klnds/gnilnd/gnilnd_aries.h
>    +++ b/lnet/klnds/gnilnd/gnilnd_aries.h
>    @@ -24,7 +24,6 @@
>     #ifndef _GNILND_ARIES_H
>     #define _GNILND_ARIES_H
> 
>    -/* for lnet_ipif_query */
>     #include <lnet/lib-lnet.h>
> 
>     #ifndef _GNILND_HSS_OPS_H
>    diff --git a/lnet/klnds/o2iblnd/o2iblnd.c b/lnet/klnds/o2iblnd/o2iblnd.c
>    index bf71ace..29335ed 100644
>    --- a/lnet/klnds/o2iblnd/o2iblnd.c
>    +++ b/lnet/klnds/o2iblnd/o2iblnd.c
>    @@ -2887,80 +2887,6 @@ kiblnd_destroy_dev(struct kib_dev *dev)
>             LIBCFS_FREE(dev, sizeof(*dev));
>     }
> 
>    -static struct kib_dev *
>    -kiblnd_create_dev(char *ifname)
>    -{
>    -	struct net_device *netdev;
>    -	struct kib_dev *dev = NULL;
>    -	int flags;
>    -	int rc;
>    -
>    -	rtnl_lock();
>    -	for_each_netdev(&init_net, netdev) {
>    -		struct in_device *in_dev;
>    -
>    -		if (strcmp(netdev->name, "lo") == 0) /* skip the loopback IF */
>    -			continue;
>    -
>    -		flags = dev_get_flags(netdev);
>    -		if (!(flags & IFF_UP)) {
>    -			CERROR("Can't query IPoIB interface %s: it's down\n",
>    -			       netdev->name);
>    -			goto unlock;
>    -		}
>    -
>    -		in_dev = __in_dev_get_rtnl(netdev);
>    -		if (!in_dev) {
>    -			CWARN("Interface %s has no IPv4 status.\n",
>    -			      netdev->name);
>    -			goto unlock;
>    -		}
>    -
>    -		for_ifa(in_dev)
>    -			if (strcmp(ifname, ifa->ifa_label) == 0) {
>    -				LIBCFS_ALLOC(dev, sizeof(*dev));
>    -				if (!dev)
>    -					goto unlock;
>    -
>    -				dev->ibd_can_failover = !!(flags & IFF_MASTER);
>    -				dev->ibd_ifip = ntohl(ifa->ifa_local);
>    -
>    -				INIT_LIST_HEAD(&dev->ibd_nets);
>    -				INIT_LIST_HEAD(&dev->ibd_list); /* not yet in kib_devs */
>    -				INIT_LIST_HEAD(&dev->ibd_fail_list);
>    -				break;
>    -			}
>    -		endfor_ifa(in_dev);
>    -	}
>    -	rtnl_unlock();
>    -
>    -	if (!dev) {
>    -		CERROR("Can't find any usable interfaces\n");
>    -		return NULL;
>    -	}
>    -
>    -	if (dev->ibd_ifip == 0) {
>    -		CERROR("Can't initialize device: no IP address\n");
>    -		goto free_dev;
>    -	}
>    -	strcpy(&dev->ibd_ifname[0], ifname);
>    -
>    -	/* initialize the device */
>    -	rc = kiblnd_dev_failover(dev);
>    -	if (rc != 0) {
>    -		CERROR("Can't initialize device: %d\n", rc);
>    -		goto free_dev;
>    -	}
>    -
>    -	list_add_tail(&dev->ibd_list, &kiblnd_data.kib_devs);
>    -	return dev;
>    -unlock:
>    -	rtnl_unlock();
>    -free_dev:
>    -	LIBCFS_FREE(dev, sizeof(*dev));
>    -	return NULL;
>    -}
>    -
>     static void
>     kiblnd_base_shutdown(void)
>     {
>    @@ -3241,8 +3167,7 @@ kiblnd_start_schedulers(struct kib_sched_info *sched)
>     	return rc;
>     }
> 
>    -static int
>    -kiblnd_dev_start_threads(struct kib_dev *dev, int newdev, u32 *cpts, int ncpts)
>    +static int kiblnd_dev_start_threads(struct kib_dev *dev, u32 *cpts, int ncpts)
>     {
>     	int	cpt;
>     	int	rc;
>    @@ -3254,7 +3179,7 @@ kiblnd_dev_start_threads(struct kib_dev *dev, int newdev, u32 *cpts, int ncpts)
>     		cpt = (cpts == NULL) ? i : cpts[i];
>     		sched = kiblnd_data.kib_scheds[cpt];
> 
>    -		if (!newdev && sched->ibs_nthreads > 0)
>    +		if (sched->ibs_nthreads > 0)
>     			continue;
> 
>     		rc = kiblnd_start_schedulers(kiblnd_data.kib_scheds[cpt]);
>    @@ -3267,49 +3192,15 @@ kiblnd_dev_start_threads(struct kib_dev *dev, int newdev, u32 *cpts, int ncpts)
>     	return 0;
>     }
> 
>    -static struct kib_dev *
>    -kiblnd_dev_search(char *ifname)
>    -{
>    -	struct kib_dev *alias = NULL;
>    -	struct kib_dev *dev;
>    -	char		*colon;
>    -	char		*colon2;
>    -
>    -	colon = strchr(ifname, ':');
>    -	list_for_each_entry(dev, &kiblnd_data.kib_devs, ibd_list) {
>    -		if (strcmp(&dev->ibd_ifname[0], ifname) == 0)
>    -			return dev;
>    -
>    -		if (alias != NULL)
>    -			continue;
>    -
>    -		colon2 = strchr(dev->ibd_ifname, ':');
>    -		if (colon != NULL)
>    -			*colon = 0;
>    -		if (colon2 != NULL)
>    -			*colon2 = 0;
>    -
>    -		if (strcmp(&dev->ibd_ifname[0], ifname) == 0)
>    -			alias = dev;
>    -
>    -		if (colon != NULL)
>    -			*colon = ':';
>    -		if (colon2 != NULL)
>    -			*colon2 = ':';
>    -	}
>    -	return alias;
>    -}
>    -
>     static int
>     kiblnd_startup(struct lnet_ni *ni)
>     {
>    -        char                     *ifname;
>     	struct kib_dev *ibdev = NULL;
>    +	struct lnet_inetdev ifaces;
>     	struct kib_net *net;
>             unsigned long             flags;
>             int                       rc;
>    -	int			  newdev;
>    -	int			  node_id;
>    +	int i;
> 
>             LASSERT (ni->ni_net->net_lnd == &the_o2iblnd);
> 
>    @@ -3333,43 +3224,65 @@ kiblnd_startup(struct lnet_ni *ni)
>     	 * tcp bonding for ksocklnd. Multi-Rail wants each secondary
>     	 * IP to be treated as an unique 'struct ni' interfaces instead.
>     	 */
>    -	if (ni->ni_interfaces[0] != NULL) {
>    -		/* Use the IPoIB interface specified in 'networks=' */
>    -
>    -		CLASSERT(LNET_INTERFACES_NUM > 1);
>    -		if (ni->ni_interfaces[1] != NULL) {
>    -			CERROR("Multiple interfaces not supported\n");
>    +	ifaces.li_interfaces = 0;
>    +	if (!ni->ni_interfaces[0]) {
>    +		rc = lnet_inet_enumerate(ni, &ifaces, NULL, 0);
>    +		if (rc < 0)
>     			goto failed;
>    -		}
>    -
>    -		ifname = ni->ni_interfaces[0];
>     	} else {
>    -		ifname = *kiblnd_tunables.kib_default_ipif;
>    +		for (i = 0; i < LNET_INTERFACES_NUM; i++) {
>    +			int j;
>    +
>    +			if (!ni->ni_interfaces[i])
>    +				break;
>    +
>    +			for (j = 0; j < LNET_INTERFACES_NUM; j++) {
>    +				if (strlen(ifaces.li_name[j]) &&
>    +				    !strcmp(ifaces.li_name[j],
>    +					    ni->ni_interfaces[i])) {
>    +					CERROR("found duplicate %s\n",
>    +					       ni->ni_interfaces[i]);
>    +					rc = -EEXIST;
>    +					goto failed;
>    +				}
>    +			}
>    +
>    +			rc = lnet_inet_enumerate(ni, &ifaces,
>    +						 ni->ni_interfaces[i], 0);
>    +			if (rc < 0)
>    +				goto failed;
>    +		}
>     	}
> 
>    -        if (strlen(ifname) >= sizeof(ibdev->ibd_ifname)) {
>    -                CERROR("IPoIB interface name too long: %s\n", ifname);
>    -                goto failed;
>    -        }
>    +	for (i = 0; i < ifaces.li_interfaces; i++) {
>    +		LIBCFS_ALLOC(ibdev, sizeof(*ibdev));
>    +		if (!ibdev)
>    +			goto failed;
> 
>    -	ibdev = kiblnd_dev_search(ifname);
>    +		ibdev->ibd_ifip = ifaces.li_ipaddr[i];
>    +		ibdev->ibd_can_failover = !!(ifaces.li_flags & IFF_MASTER);
>    +		strlcpy(ibdev->ibd_ifname, ifaces.li_name[i],
>    +			sizeof(ibdev->ibd_ifname));
> 
>    -	newdev = ibdev == NULL;
>    -	/* hmm...create kib_dev even for alias */
>    -	if (ibdev == NULL || strcmp(&ibdev->ibd_ifname[0], ifname) != 0)
>    -		ibdev = kiblnd_create_dev(ifname);
>    +		INIT_LIST_HEAD(&ibdev->ibd_nets);
>    +		INIT_LIST_HEAD(&ibdev->ibd_list); /* not yet in kib_devs */
>    +		INIT_LIST_HEAD(&ibdev->ibd_fail_list);
> 
>    -	if (ibdev == NULL)
>    -		goto failed;
>    +		/* initialize the device */
>    +		rc = kiblnd_dev_failover(ibdev);
>    +		if (rc) {
>    +			CERROR("Can't initialize device: %d\n", rc);
>    +			LIBCFS_FREE(ibdev, sizeof(*ibdev));
>    +			goto failed;
>    +		}
> 
>    -	node_id = dev_to_node(ibdev->ibd_hdev->ibh_ibdev->dma_device);
>    -	ni->ni_dev_cpt = cfs_cpt_of_node(lnet_cpt_table(), node_id);
>    +		list_add_tail(&ibdev->ibd_list, &kiblnd_data.kib_devs);
>    +	}
> 
>     	net->ibn_dev = ibdev;
>     	ni->ni_nid = LNET_MKNID(LNET_NIDNET(ni->ni_nid), ibdev->ibd_ifip);
> 
>    -	rc = kiblnd_dev_start_threads(ibdev, newdev,
>    -				      ni->ni_cpts, ni->ni_ncpts);
>    +	rc = kiblnd_dev_start_threads(ibdev, ni->ni_cpts, ni->ni_ncpts);
>     	if (rc != 0)
>     		goto failed;
> 
>    diff --git a/lnet/klnds/socklnd/socklnd.c b/lnet/klnds/socklnd/socklnd.c
>    index 9cabeec..1657413 100644
>    --- a/lnet/klnds/socklnd/socklnd.c
>    +++ b/lnet/klnds/socklnd/socklnd.c
>    @@ -2571,62 +2571,6 @@ ksocknal_shutdown(struct lnet_ni *ni)
>     }
> 
>     static int
>    -ksocknal_enumerate_interfaces(struct ksock_net *net, char *iname)
>    -{
>    -	struct net_device *dev;
>    -
>    -	rtnl_lock();
>    -	for_each_netdev(&init_net, dev) {
>    -		/* The iname specified by an user land configuration can
>    -		 * map to an ifa_label so always treat iname as an ifa_label.
>    -		 * If iname is NULL then fall back to the net device name.
>    -		 */
>    -		const char *name = iname ? iname : dev->name;
>    -		struct in_device *in_dev;
>    -
>    -		if (strcmp(dev->name, "lo") == 0) /* skip the loopback IF */
>    -			continue;
>    -
>    -		if (!(dev_get_flags(dev) & IFF_UP)) {
>    -			CWARN("Ignoring interface %s (down)\n", dev->name);
>    -			continue;
>    -		}
>    -
>    -		in_dev = __in_dev_get_rtnl(dev);
>    -		if (!in_dev) {
>    -			CWARN("Interface %s has no IPv4 status.\n", dev->name);
>    -			continue;
>    -		}
>    -
>    -		for_ifa(in_dev)
>    -			if (strcmp(name, ifa->ifa_label) == 0) {
>    -				int idx = net->ksnn_ninterfaces;
>    -				struct ksock_interface *ksi;
>    -
>    -				if (idx >= ARRAY_SIZE(net->ksnn_interfaces)) {
>    -					rtnl_unlock();
>    -					return -E2BIG;
>    -				}
>    -
>    -				ksi = &net->ksnn_interfaces[idx];
>    -				ksi->ksni_ipaddr = ntohl(ifa->ifa_local);
>    -				ksi->ksni_netmask = ifa->ifa_mask;
>    -				strlcpy(ksi->ksni_name,
>    -					name, sizeof(ksi->ksni_name));
>    -				net->ksnn_ninterfaces++;
>    -				break;
>    -			}
>    -		endfor_ifa(in_dev);
>    -        }
>    -	rtnl_unlock();
>    -
>    -	if (net->ksnn_ninterfaces == 0)
>    -                CERROR("Can't find any usable interfaces\n");
>    -
>    -	return net->ksnn_ninterfaces > 0 ? 0 : -ENOENT;
>    -}
>    -
>    -static int
>     ksocknal_search_new_ipif(struct ksock_net *net)
>     {
>     	int new_ipif = 0;
>    @@ -2743,12 +2687,11 @@ ksocknal_net_start_threads(struct ksock_net *net, __u32 *cpts, int ncpts)
>     int
>     ksocknal_startup(struct lnet_ni *ni)
>     {
>    -	struct ksock_net *net;
>     	struct lnet_ioctl_config_lnd_cmn_tunables *net_tunables;
>    +	struct lnet_inetdev ifaces;
>    +	struct ksock_net *net;
>     	int rc;
>     	int i;
>    -	struct net_device *net_dev;
>    -	int node_id;
> 
>             LASSERT (ni->ni_net->net_lnd == &the_ksocklnd);
> 
>    @@ -2788,8 +2731,9 @@ ksocknal_startup(struct lnet_ni *ni)
>     		net_tunables->lct_peer_rtr_credits =
>     			*ksocknal_tunables.ksnd_peerrtrcredits;
> 
>    +	ifaces.li_interfaces = 0;
>     	if (!ni->ni_interfaces[0]) {
>    -		rc = ksocknal_enumerate_interfaces(net, NULL);
>    +		rc = lnet_inet_enumerate(ni, &ifaces, NULL, 0);
>     		if (rc < 0)
>     			goto fail_1;
>     	} else {
>    @@ -2809,34 +2753,32 @@ ksocknal_startup(struct lnet_ni *ni)
>     			if (!ni->ni_interfaces[i])
>     				break;
> 
>    -			for (j = 0; j < net->ksnn_ninterfaces;  j++) {
>    -				struct ksock_interface *ksi;
>    -
>    -				ksi = &net->ksnn_interfaces[j];
>    -
>    -				if (strcmp(ni->ni_interfaces[i],
>    -					   ksi->ksni_name) == 0) {
>    +			for (j = 0; j < LNET_INTERFACES_NUM;  j++) {
>    +				if (strcmp(ifaces.li_name[j],
>    +					   ni->ni_interfaces[i]) == 0) {
>     					CERROR("found duplicate %s\n",
>    -					       ksi->ksni_name);
>    +					       ni->ni_interfaces[i]);
>     					rc = -EEXIST;
>     					goto fail_1;
>     				}
>     			}
> 
>    -			rc = ksocknal_enumerate_interfaces(net, ni->ni_interfaces[i]);
>    +			rc = lnet_inet_enumerate(ni, &ifaces,
>    +						 ni->ni_interfaces[i], 0);
>     			if (rc < 0)
>     				goto fail_1;
>     		}
>     	}
> 
>    -	net_dev = dev_get_by_name(&init_net,
>    -				  net->ksnn_interfaces[0].ksni_name);
>    -	if (net_dev != NULL) {
>    -		node_id = dev_to_node(&net_dev->dev);
>    -		ni->ni_dev_cpt = cfs_cpt_of_node(lnet_cpt_table(), node_id);
>    -		dev_put(net_dev);
>    -	} else {
>    -		ni->ni_dev_cpt = CFS_CPT_ANY;
>    +	net->ksnn_ninterfaces = ifaces.li_interfaces;
>    +	for (i = 0; i < net->ksnn_ninterfaces; i++) {
>    +		struct ksock_interface *ksi;
>    +
>    +		ksi = &net->ksnn_interfaces[i];
>    +		ksi->ksni_ipaddr = ifaces.li_ipaddr[i];
>    +		ksi->ksni_netmask = ifaces.li_netmask[i];
>    +		strlcpy(ksi->ksni_name, ifaces.li_name[i],
>    +			sizeof(ksi->ksni_name));
>     	}
> 
>     	/* call it before add it to ksocknal_data.ksnd_nets */
>    diff --git a/lnet/lnet/config.c b/lnet/lnet/config.c
>    index 12b2442..666f0f0 100644
>    --- a/lnet/lnet/config.c
>    +++ b/lnet/lnet/config.c
>    @@ -1611,34 +1611,28 @@ lnet_match_networks (char **networksp, char *ip2nets, __u32 *ipaddrs, int nip)
>     	return count;
>     }
> 
>    -static void
>    -lnet_ipaddr_free_enumeration(__u32 *ipaddrs, int nip)
>    -{
>    -	LIBCFS_FREE(ipaddrs, nip * sizeof(*ipaddrs));
>    -}
>    -
>    -static int
>    -lnet_ipaddr_enumerate(u32 **ipaddrsp)
>    +int lnet_inet_enumerate(struct lnet_ni *ni, struct lnet_inetdev *ifaces,
>    +			char *iname, int ifa_done)
>     {
>     	struct net_device *dev;
>    -	u32 *ipaddrs;
>    -	int nalloc = 64;
>    -	int nip = 0;
>    -
>    -	LIBCFS_ALLOC(ipaddrs, nalloc * sizeof(*ipaddrs));
>    -	if (!ipaddrs) {
>    -		CERROR("Can't allocate ipaddrs[%d]\n", nalloc);
>    -		return -ENOMEM;
>    -	}
>    +	int skip = 0;
>    +	int rc = 0;
> 
>     	rtnl_lock();
>     	for_each_netdev(&init_net, dev) {
>    +		/* The iname specified by an user land configuration can
>    +		 * map to an ifa_label so always treat iname as an ifa_label.
>    +		 * If iname is NULL then fall back to the net device name.
>    +		 */
>    +		const char *name = iname ? iname : dev->name;
>     		struct in_device *in_dev;
> 
>    -		if (strcmp(dev->name, "lo") == 0)
>    +		ifaces->li_flags = dev_get_flags(dev);
>    +
>    +		if (ifaces->li_flags & IFF_LOOPBACK) /* skip the loopback IF */
>     			continue;
> 
>    -		if (!(dev_get_flags(dev) & IFF_UP)) {
>    +		if (!(ifaces->li_flags & IFF_UP)) {
>     			CWARN("Ignoring interface %s: it's down\n", dev->name);
>     			continue;
>     		}
>    @@ -1649,65 +1643,109 @@ lnet_ipaddr_enumerate(u32 **ipaddrsp)
>     			continue;
>     		}
> 
>    -		if (nip >= nalloc) {
>    -			u32 *ipaddrs2;
>    +		if (ni && ni->ni_dev_cpt != CFS_CPT_ANY) {
>    +			int node_id = dev_to_node(&dev->dev);
>    +			int cpt = cfs_cpt_of_node(lnet_cpt_table(), node_id);
> 
>    -			nalloc += nalloc;
>    -			ipaddrs2 = krealloc(ipaddrs, nalloc * sizeof(*ipaddrs2),
>    -					    GFP_KERNEL);
>    -			if (!ipaddrs2) {
>    -				kfree(ipaddrs);
>    -				CERROR("Can't allocate ipaddrs[%d]\n", nip);
>    -				return -ENOMEM;
>    +			if (ni->ni_dev_cpt != cpt &&
>    +			    ifaces->li_interfaces > 0) {
>    +				ni->ni_dev_cpt = CFS_CPT_ANY;
>    +				CWARN("Not all the network interfaces belong to the same CPT\n");
>    +			} else {
>    +				ni->ni_dev_cpt = cpt;
>     			}
>    -			ipaddrs = ipaddrs2;
>     		}
> 
>    -		for_primary_ifa(in_dev)
>    -			if (strcmp(ifa->ifa_label, dev->name) == 0) {
>    -				ipaddrs[nip++] = ifa->ifa_local;
>    -				break;
>    +		for_ifa(in_dev)
>    +			if (strcmp(name, ifa->ifa_label) == 0) {
>    +				int idx = ifaces->li_interfaces;
>    +
>    +				if (idx >= ARRAY_SIZE(ifaces->li_name))
>    +					return -E2BIG;
>    +
>    +				if (skip++ < ifa_done)
>    +					continue;
>    +
>    +				ifaces->li_ipaddr[idx] = ntohl(ifa->ifa_local);
>    +				ifaces->li_netmask[idx] = ifa->ifa_mask;
>    +				strlcpy(ifaces->li_name[idx], name,
>    +					sizeof(ifaces->li_name[idx]));
>    +				ifaces->li_interfaces++;
>    +				goto unlock_rtnl;
>     			}
>     		endfor_ifa(in_dev);
>     	}
>    +unlock_rtnl:
>     	rtnl_unlock();
> 
>    -	*ipaddrsp = ipaddrs;
>    -	return nip;
>    +	if (ifaces->li_interfaces == 0) {
>    +		CERROR("Can't find any usable interfaces\n");
>    +		rc = -ENOENT;
>    +	}
>    +
>    +	return rc;
>     }
>    +EXPORT_SYMBOL(lnet_inet_enumerate);
> 
>     int
>    -lnet_parse_ip2nets (char **networksp, char *ip2nets)
>    +lnet_parse_ip2nets(char **networksp, char *ip2nets)
>     {
>    -	__u32	  *ipaddrs = NULL;
>    -	int	   nip = lnet_ipaddr_enumerate(&ipaddrs);
>    -	int	   rc;
>    -
>    -	if (nip < 0) {
>    -		LCONSOLE_ERROR_MSG(0x117, "Error %d enumerating local IP "
>    -				   "interfaces for ip2nets to match\n", nip);
>    -		return nip;
>    -	}
>    +	struct lnet_inetdev ifaces;
>    +	u32 *ipaddrs = NULL;
>    +	int nalloc = 0;
>    +	int nip = 0;
>    +	int rc;
> 
>    -	if (nip == 0) {
>    -		LCONSOLE_ERROR_MSG(0x118, "No local IP interfaces "
>    -				   "for ip2nets to match\n");
>    -		return -ENOENT;
>    -	}
>    +realloc:
>    +	ifaces.li_interfaces = 0;
>    +	rc = lnet_inet_enumerate(NULL, &ifaces, NULL, nip);
>    +	if (rc < 0) {
>    +		/* Handle edge case where we nip is muliple of
>    +		 * LNET_INTERFACES_NUM and no more devices are
>    +		 * detected.
>    +		 */
>    +		if (rc == -ENOENT && nip > 0)
>    +			goto match_networks;
> 
>    -	rc = lnet_match_networks(networksp, ip2nets, ipaddrs, nip);
>    -	lnet_ipaddr_free_enumeration(ipaddrs, nip);
>    +		LCONSOLE_ERROR_MSG(0x117,
>    +				   "Error %d enumerating local IP interfaces for ip2nets to match\n",
>    +				   rc);
>    +		goto out_free_addrs;
>    +	} else {
>    +		u32 *ipaddrs2;
>    +		int i;
>    +
>    +		nalloc += ifaces.li_interfaces;
>    +		ipaddrs2 = krealloc(ipaddrs, nalloc * sizeof(*ipaddrs),
>    +				    GFP_KERNEL);
>    +		if (!ipaddrs2) {
>    +			CERROR("Can't allocate ipaddrs[%d]\n", nalloc);
>    +			goto out_free_addrs;
>    +		}
>    +		ipaddrs = ipaddrs2;
> 
>    +		for (i = 0; i < ifaces.li_interfaces; i++) {
>    +			memcpy(ipaddrs + nip, ifaces.li_ipaddr,
>    +			       sizeof(*ipaddrs) * LNET_INTERFACES_NUM);
>    +		}
>    +
>    +		/* Maybe more ? */
>    +		if (ifaces.li_interfaces == LNET_INTERFACES_NUM) {
>    +			nip += LNET_INTERFACES_NUM;
>    +			goto realloc;
>    +		}
>    +	}
>    +match_networks:
>    +	rc = lnet_match_networks(networksp, ip2nets, ipaddrs, nip);
>     	if (rc < 0) {
>     		LCONSOLE_ERROR_MSG(0x119, "Error %d parsing ip2nets\n", rc);
>     		return rc;
>    -	}
>    -
>    -	if (rc == 0) {
>    +	} else if (rc == 0) {
>     		LCONSOLE_ERROR_MSG(0x11a, "ip2nets does not match "
>     				   "any local IP interfaces\n");
>     		return -ENOENT;
>     	}
>    -
>    -	return 0;
>    +out_free_addrs:
>    +	LIBCFS_FREE(ipaddrs, nip * sizeof(*ipaddrs));
>    +	return rc;
>     }
>    -- 
>    1.8.3.1
> 
> 
> 
> _______________________________________________
> lustre-devel mailing list
> lustre-devel at lists.lustre.org
> http://lists.lustre.org/listinfo.cgi/lustre-devel-lustre.org

Cheers, Andreas
--
Andreas Dilger
Principal Lustre Architect
Whamcloud

^ permalink raw reply	[flat|nested] 9+ messages in thread

* [lustre-devel] lnet ip2nets option broken in master?
  2019-06-11  6:27       ` Andreas Dilger
@ 2019-06-11  9:02         ` Degremont, Aurelien
  0 siblings, 0 replies; 9+ messages in thread
From: Degremont, Aurelien @ 2019-06-11  9:02 UTC (permalink / raw)
  To: lustre-devel

Since, dependencies have landed and James pushed its patch, https://review.whamcloud.com/#/c/34993/
I don't want to have a patch competing with this one if this one is likely to land.



?Le 11/06/2019 08:28, ? Andreas Dilger ? <adilger@whamcloud.com> a ?crit :

    Aurelien,
    I just saw your reply in my junk folder... :-(
    
    Could you please open an LU ticket, and possibly push a patch with the fix
    that is working for you, rather than me guessing what is supposed to be done.
    
    Cheers, Andreas
    
    On May 28, 2019, at 07:57, Degremont, Aurelien <degremoa@amazon.com> wrote:
    > 
    > Oh, I was thinking of a smaller change.
    > This patch looks like (good) code refactoring.
    > 
    > It seems the fix for ip2nets in master is indeed just a "ntohl(ifa->ifa_local);" for lnet_ipaddr_enumerate()
    > 
    > 
    > Aur?lien
    > 
    > Le 28/05/2019 15:13, ? James Simmons ? <jsimmons@infradead.org> a ?crit :
    > 
    > 
    >    On Mon, 27 May 2019, Degremont, Aurelien wrote:
    > 
    >> Hi Chris,
    >> 
    >> Thanks for the info!
    >> 
    >> @James, most of the patches you were waiting for are almost landed (last 
    >    ones are in master-next).
    >> Do you have a draft of the fix for ip2nets you can push in gerrit 
    >    fortestsonly?
    > 
    >    Yes I do but I need the the ko2iblnd fix to land as well. I embedded the
    >    patch if you want to do an early review. This is a rough version but does
    >    have light testing. I have some style changes to be sepatated out but 
    >    haven't got to it yet. I made this patch some time ago. So Neil be gentle 
    >    :-)
    > 
    >    diff --git a/lnet/include/lnet/lib-lnet.h b/lnet/include/lnet/lib-lnet.h
    >    index 95c4df1..2eb161e 100644
    >    --- a/lnet/include/lnet/lib-lnet.h
    >    +++ b/lnet/include/lnet/lib-lnet.h
    >    @@ -40,9 +40,7 @@
    >     /* LNET has 0xeXXX */
    >     #define CFS_FAIL_PTLRPC_OST_BULK_CB2	0xe000
    > 
    >    -#ifndef __KERNEL__
    >    -# error This include is only for kernel use.
    >    -#endif
    >    +#include <linux/netdevice.h>
    > 
    >     #include <libcfs/libcfs.h>
    >     #include <lnet/api.h>
    >    @@ -841,6 +839,16 @@ int lnet_acceptor_port(void);
    >     int lnet_acceptor_start(void);
    >     void lnet_acceptor_stop(void);
    > 
    >    +struct lnet_inetdev {
    >    +	unsigned int	li_interfaces;
    >    +	int		li_flags;
    >    +	u32		li_ipaddr[LNET_INTERFACES_NUM];
    >    +	u32		li_netmask[LNET_INTERFACES_NUM];
    >    +	char		li_name[LNET_INTERFACES_NUM][IFNAMSIZ];
    >    +};
    >    +
    >    +int lnet_inet_enumerate(struct lnet_ni *ni, struct lnet_inetdev *ifaces,
    >    +			char *iname, int ifaces_done);
    >     int lnet_sock_setbuf(struct socket *socket, int txbufsize, int rxbufsize);
    >     int lnet_sock_getbuf(struct socket *socket, int *txbufsize, int *rxbufsize);
    >     int lnet_sock_getaddr(struct socket *socket, bool remote, __u32 *ip, int *port);
    >    diff --git a/lnet/klnds/gnilnd/gnilnd_aries.h b/lnet/klnds/gnilnd/gnilnd_aries.h
    >    index d9698b6..431442f 100644
    >    --- a/lnet/klnds/gnilnd/gnilnd_aries.h
    >    +++ b/lnet/klnds/gnilnd/gnilnd_aries.h
    >    @@ -24,7 +24,6 @@
    >     #ifndef _GNILND_ARIES_H
    >     #define _GNILND_ARIES_H
    > 
    >    -/* for lnet_ipif_query */
    >     #include <lnet/lib-lnet.h>
    > 
    >     #ifndef _GNILND_HSS_OPS_H
    >    diff --git a/lnet/klnds/o2iblnd/o2iblnd.c b/lnet/klnds/o2iblnd/o2iblnd.c
    >    index bf71ace..29335ed 100644
    >    --- a/lnet/klnds/o2iblnd/o2iblnd.c
    >    +++ b/lnet/klnds/o2iblnd/o2iblnd.c
    >    @@ -2887,80 +2887,6 @@ kiblnd_destroy_dev(struct kib_dev *dev)
    >             LIBCFS_FREE(dev, sizeof(*dev));
    >     }
    > 
    >    -static struct kib_dev *
    >    -kiblnd_create_dev(char *ifname)
    >    -{
    >    -	struct net_device *netdev;
    >    -	struct kib_dev *dev = NULL;
    >    -	int flags;
    >    -	int rc;
    >    -
    >    -	rtnl_lock();
    >    -	for_each_netdev(&init_net, netdev) {
    >    -		struct in_device *in_dev;
    >    -
    >    -		if (strcmp(netdev->name, "lo") == 0) /* skip the loopback IF */
    >    -			continue;
    >    -
    >    -		flags = dev_get_flags(netdev);
    >    -		if (!(flags & IFF_UP)) {
    >    -			CERROR("Can't query IPoIB interface %s: it's down\n",
    >    -			       netdev->name);
    >    -			goto unlock;
    >    -		}
    >    -
    >    -		in_dev = __in_dev_get_rtnl(netdev);
    >    -		if (!in_dev) {
    >    -			CWARN("Interface %s has no IPv4 status.\n",
    >    -			      netdev->name);
    >    -			goto unlock;
    >    -		}
    >    -
    >    -		for_ifa(in_dev)
    >    -			if (strcmp(ifname, ifa->ifa_label) == 0) {
    >    -				LIBCFS_ALLOC(dev, sizeof(*dev));
    >    -				if (!dev)
    >    -					goto unlock;
    >    -
    >    -				dev->ibd_can_failover = !!(flags & IFF_MASTER);
    >    -				dev->ibd_ifip = ntohl(ifa->ifa_local);
    >    -
    >    -				INIT_LIST_HEAD(&dev->ibd_nets);
    >    -				INIT_LIST_HEAD(&dev->ibd_list); /* not yet in kib_devs */
    >    -				INIT_LIST_HEAD(&dev->ibd_fail_list);
    >    -				break;
    >    -			}
    >    -		endfor_ifa(in_dev);
    >    -	}
    >    -	rtnl_unlock();
    >    -
    >    -	if (!dev) {
    >    -		CERROR("Can't find any usable interfaces\n");
    >    -		return NULL;
    >    -	}
    >    -
    >    -	if (dev->ibd_ifip == 0) {
    >    -		CERROR("Can't initialize device: no IP address\n");
    >    -		goto free_dev;
    >    -	}
    >    -	strcpy(&dev->ibd_ifname[0], ifname);
    >    -
    >    -	/* initialize the device */
    >    -	rc = kiblnd_dev_failover(dev);
    >    -	if (rc != 0) {
    >    -		CERROR("Can't initialize device: %d\n", rc);
    >    -		goto free_dev;
    >    -	}
    >    -
    >    -	list_add_tail(&dev->ibd_list, &kiblnd_data.kib_devs);
    >    -	return dev;
    >    -unlock:
    >    -	rtnl_unlock();
    >    -free_dev:
    >    -	LIBCFS_FREE(dev, sizeof(*dev));
    >    -	return NULL;
    >    -}
    >    -
    >     static void
    >     kiblnd_base_shutdown(void)
    >     {
    >    @@ -3241,8 +3167,7 @@ kiblnd_start_schedulers(struct kib_sched_info *sched)
    >     	return rc;
    >     }
    > 
    >    -static int
    >    -kiblnd_dev_start_threads(struct kib_dev *dev, int newdev, u32 *cpts, int ncpts)
    >    +static int kiblnd_dev_start_threads(struct kib_dev *dev, u32 *cpts, int ncpts)
    >     {
    >     	int	cpt;
    >     	int	rc;
    >    @@ -3254,7 +3179,7 @@ kiblnd_dev_start_threads(struct kib_dev *dev, int newdev, u32 *cpts, int ncpts)
    >     		cpt = (cpts == NULL) ? i : cpts[i];
    >     		sched = kiblnd_data.kib_scheds[cpt];
    > 
    >    -		if (!newdev && sched->ibs_nthreads > 0)
    >    +		if (sched->ibs_nthreads > 0)
    >     			continue;
    > 
    >     		rc = kiblnd_start_schedulers(kiblnd_data.kib_scheds[cpt]);
    >    @@ -3267,49 +3192,15 @@ kiblnd_dev_start_threads(struct kib_dev *dev, int newdev, u32 *cpts, int ncpts)
    >     	return 0;
    >     }
    > 
    >    -static struct kib_dev *
    >    -kiblnd_dev_search(char *ifname)
    >    -{
    >    -	struct kib_dev *alias = NULL;
    >    -	struct kib_dev *dev;
    >    -	char		*colon;
    >    -	char		*colon2;
    >    -
    >    -	colon = strchr(ifname, ':');
    >    -	list_for_each_entry(dev, &kiblnd_data.kib_devs, ibd_list) {
    >    -		if (strcmp(&dev->ibd_ifname[0], ifname) == 0)
    >    -			return dev;
    >    -
    >    -		if (alias != NULL)
    >    -			continue;
    >    -
    >    -		colon2 = strchr(dev->ibd_ifname, ':');
    >    -		if (colon != NULL)
    >    -			*colon = 0;
    >    -		if (colon2 != NULL)
    >    -			*colon2 = 0;
    >    -
    >    -		if (strcmp(&dev->ibd_ifname[0], ifname) == 0)
    >    -			alias = dev;
    >    -
    >    -		if (colon != NULL)
    >    -			*colon = ':';
    >    -		if (colon2 != NULL)
    >    -			*colon2 = ':';
    >    -	}
    >    -	return alias;
    >    -}
    >    -
    >     static int
    >     kiblnd_startup(struct lnet_ni *ni)
    >     {
    >    -        char                     *ifname;
    >     	struct kib_dev *ibdev = NULL;
    >    +	struct lnet_inetdev ifaces;
    >     	struct kib_net *net;
    >             unsigned long             flags;
    >             int                       rc;
    >    -	int			  newdev;
    >    -	int			  node_id;
    >    +	int i;
    > 
    >             LASSERT (ni->ni_net->net_lnd == &the_o2iblnd);
    > 
    >    @@ -3333,43 +3224,65 @@ kiblnd_startup(struct lnet_ni *ni)
    >     	 * tcp bonding for ksocklnd. Multi-Rail wants each secondary
    >     	 * IP to be treated as an unique 'struct ni' interfaces instead.
    >     	 */
    >    -	if (ni->ni_interfaces[0] != NULL) {
    >    -		/* Use the IPoIB interface specified in 'networks=' */
    >    -
    >    -		CLASSERT(LNET_INTERFACES_NUM > 1);
    >    -		if (ni->ni_interfaces[1] != NULL) {
    >    -			CERROR("Multiple interfaces not supported\n");
    >    +	ifaces.li_interfaces = 0;
    >    +	if (!ni->ni_interfaces[0]) {
    >    +		rc = lnet_inet_enumerate(ni, &ifaces, NULL, 0);
    >    +		if (rc < 0)
    >     			goto failed;
    >    -		}
    >    -
    >    -		ifname = ni->ni_interfaces[0];
    >     	} else {
    >    -		ifname = *kiblnd_tunables.kib_default_ipif;
    >    +		for (i = 0; i < LNET_INTERFACES_NUM; i++) {
    >    +			int j;
    >    +
    >    +			if (!ni->ni_interfaces[i])
    >    +				break;
    >    +
    >    +			for (j = 0; j < LNET_INTERFACES_NUM; j++) {
    >    +				if (strlen(ifaces.li_name[j]) &&
    >    +				    !strcmp(ifaces.li_name[j],
    >    +					    ni->ni_interfaces[i])) {
    >    +					CERROR("found duplicate %s\n",
    >    +					       ni->ni_interfaces[i]);
    >    +					rc = -EEXIST;
    >    +					goto failed;
    >    +				}
    >    +			}
    >    +
    >    +			rc = lnet_inet_enumerate(ni, &ifaces,
    >    +						 ni->ni_interfaces[i], 0);
    >    +			if (rc < 0)
    >    +				goto failed;
    >    +		}
    >     	}
    > 
    >    -        if (strlen(ifname) >= sizeof(ibdev->ibd_ifname)) {
    >    -                CERROR("IPoIB interface name too long: %s\n", ifname);
    >    -                goto failed;
    >    -        }
    >    +	for (i = 0; i < ifaces.li_interfaces; i++) {
    >    +		LIBCFS_ALLOC(ibdev, sizeof(*ibdev));
    >    +		if (!ibdev)
    >    +			goto failed;
    > 
    >    -	ibdev = kiblnd_dev_search(ifname);
    >    +		ibdev->ibd_ifip = ifaces.li_ipaddr[i];
    >    +		ibdev->ibd_can_failover = !!(ifaces.li_flags & IFF_MASTER);
    >    +		strlcpy(ibdev->ibd_ifname, ifaces.li_name[i],
    >    +			sizeof(ibdev->ibd_ifname));
    > 
    >    -	newdev = ibdev == NULL;
    >    -	/* hmm...create kib_dev even for alias */
    >    -	if (ibdev == NULL || strcmp(&ibdev->ibd_ifname[0], ifname) != 0)
    >    -		ibdev = kiblnd_create_dev(ifname);
    >    +		INIT_LIST_HEAD(&ibdev->ibd_nets);
    >    +		INIT_LIST_HEAD(&ibdev->ibd_list); /* not yet in kib_devs */
    >    +		INIT_LIST_HEAD(&ibdev->ibd_fail_list);
    > 
    >    -	if (ibdev == NULL)
    >    -		goto failed;
    >    +		/* initialize the device */
    >    +		rc = kiblnd_dev_failover(ibdev);
    >    +		if (rc) {
    >    +			CERROR("Can't initialize device: %d\n", rc);
    >    +			LIBCFS_FREE(ibdev, sizeof(*ibdev));
    >    +			goto failed;
    >    +		}
    > 
    >    -	node_id = dev_to_node(ibdev->ibd_hdev->ibh_ibdev->dma_device);
    >    -	ni->ni_dev_cpt = cfs_cpt_of_node(lnet_cpt_table(), node_id);
    >    +		list_add_tail(&ibdev->ibd_list, &kiblnd_data.kib_devs);
    >    +	}
    > 
    >     	net->ibn_dev = ibdev;
    >     	ni->ni_nid = LNET_MKNID(LNET_NIDNET(ni->ni_nid), ibdev->ibd_ifip);
    > 
    >    -	rc = kiblnd_dev_start_threads(ibdev, newdev,
    >    -				      ni->ni_cpts, ni->ni_ncpts);
    >    +	rc = kiblnd_dev_start_threads(ibdev, ni->ni_cpts, ni->ni_ncpts);
    >     	if (rc != 0)
    >     		goto failed;
    > 
    >    diff --git a/lnet/klnds/socklnd/socklnd.c b/lnet/klnds/socklnd/socklnd.c
    >    index 9cabeec..1657413 100644
    >    --- a/lnet/klnds/socklnd/socklnd.c
    >    +++ b/lnet/klnds/socklnd/socklnd.c
    >    @@ -2571,62 +2571,6 @@ ksocknal_shutdown(struct lnet_ni *ni)
    >     }
    > 
    >     static int
    >    -ksocknal_enumerate_interfaces(struct ksock_net *net, char *iname)
    >    -{
    >    -	struct net_device *dev;
    >    -
    >    -	rtnl_lock();
    >    -	for_each_netdev(&init_net, dev) {
    >    -		/* The iname specified by an user land configuration can
    >    -		 * map to an ifa_label so always treat iname as an ifa_label.
    >    -		 * If iname is NULL then fall back to the net device name.
    >    -		 */
    >    -		const char *name = iname ? iname : dev->name;
    >    -		struct in_device *in_dev;
    >    -
    >    -		if (strcmp(dev->name, "lo") == 0) /* skip the loopback IF */
    >    -			continue;
    >    -
    >    -		if (!(dev_get_flags(dev) & IFF_UP)) {
    >    -			CWARN("Ignoring interface %s (down)\n", dev->name);
    >    -			continue;
    >    -		}
    >    -
    >    -		in_dev = __in_dev_get_rtnl(dev);
    >    -		if (!in_dev) {
    >    -			CWARN("Interface %s has no IPv4 status.\n", dev->name);
    >    -			continue;
    >    -		}
    >    -
    >    -		for_ifa(in_dev)
    >    -			if (strcmp(name, ifa->ifa_label) == 0) {
    >    -				int idx = net->ksnn_ninterfaces;
    >    -				struct ksock_interface *ksi;
    >    -
    >    -				if (idx >= ARRAY_SIZE(net->ksnn_interfaces)) {
    >    -					rtnl_unlock();
    >    -					return -E2BIG;
    >    -				}
    >    -
    >    -				ksi = &net->ksnn_interfaces[idx];
    >    -				ksi->ksni_ipaddr = ntohl(ifa->ifa_local);
    >    -				ksi->ksni_netmask = ifa->ifa_mask;
    >    -				strlcpy(ksi->ksni_name,
    >    -					name, sizeof(ksi->ksni_name));
    >    -				net->ksnn_ninterfaces++;
    >    -				break;
    >    -			}
    >    -		endfor_ifa(in_dev);
    >    -        }
    >    -	rtnl_unlock();
    >    -
    >    -	if (net->ksnn_ninterfaces == 0)
    >    -                CERROR("Can't find any usable interfaces\n");
    >    -
    >    -	return net->ksnn_ninterfaces > 0 ? 0 : -ENOENT;
    >    -}
    >    -
    >    -static int
    >     ksocknal_search_new_ipif(struct ksock_net *net)
    >     {
    >     	int new_ipif = 0;
    >    @@ -2743,12 +2687,11 @@ ksocknal_net_start_threads(struct ksock_net *net, __u32 *cpts, int ncpts)
    >     int
    >     ksocknal_startup(struct lnet_ni *ni)
    >     {
    >    -	struct ksock_net *net;
    >     	struct lnet_ioctl_config_lnd_cmn_tunables *net_tunables;
    >    +	struct lnet_inetdev ifaces;
    >    +	struct ksock_net *net;
    >     	int rc;
    >     	int i;
    >    -	struct net_device *net_dev;
    >    -	int node_id;
    > 
    >             LASSERT (ni->ni_net->net_lnd == &the_ksocklnd);
    > 
    >    @@ -2788,8 +2731,9 @@ ksocknal_startup(struct lnet_ni *ni)
    >     		net_tunables->lct_peer_rtr_credits =
    >     			*ksocknal_tunables.ksnd_peerrtrcredits;
    > 
    >    +	ifaces.li_interfaces = 0;
    >     	if (!ni->ni_interfaces[0]) {
    >    -		rc = ksocknal_enumerate_interfaces(net, NULL);
    >    +		rc = lnet_inet_enumerate(ni, &ifaces, NULL, 0);
    >     		if (rc < 0)
    >     			goto fail_1;
    >     	} else {
    >    @@ -2809,34 +2753,32 @@ ksocknal_startup(struct lnet_ni *ni)
    >     			if (!ni->ni_interfaces[i])
    >     				break;
    > 
    >    -			for (j = 0; j < net->ksnn_ninterfaces;  j++) {
    >    -				struct ksock_interface *ksi;
    >    -
    >    -				ksi = &net->ksnn_interfaces[j];
    >    -
    >    -				if (strcmp(ni->ni_interfaces[i],
    >    -					   ksi->ksni_name) == 0) {
    >    +			for (j = 0; j < LNET_INTERFACES_NUM;  j++) {
    >    +				if (strcmp(ifaces.li_name[j],
    >    +					   ni->ni_interfaces[i]) == 0) {
    >     					CERROR("found duplicate %s\n",
    >    -					       ksi->ksni_name);
    >    +					       ni->ni_interfaces[i]);
    >     					rc = -EEXIST;
    >     					goto fail_1;
    >     				}
    >     			}
    > 
    >    -			rc = ksocknal_enumerate_interfaces(net, ni->ni_interfaces[i]);
    >    +			rc = lnet_inet_enumerate(ni, &ifaces,
    >    +						 ni->ni_interfaces[i], 0);
    >     			if (rc < 0)
    >     				goto fail_1;
    >     		}
    >     	}
    > 
    >    -	net_dev = dev_get_by_name(&init_net,
    >    -				  net->ksnn_interfaces[0].ksni_name);
    >    -	if (net_dev != NULL) {
    >    -		node_id = dev_to_node(&net_dev->dev);
    >    -		ni->ni_dev_cpt = cfs_cpt_of_node(lnet_cpt_table(), node_id);
    >    -		dev_put(net_dev);
    >    -	} else {
    >    -		ni->ni_dev_cpt = CFS_CPT_ANY;
    >    +	net->ksnn_ninterfaces = ifaces.li_interfaces;
    >    +	for (i = 0; i < net->ksnn_ninterfaces; i++) {
    >    +		struct ksock_interface *ksi;
    >    +
    >    +		ksi = &net->ksnn_interfaces[i];
    >    +		ksi->ksni_ipaddr = ifaces.li_ipaddr[i];
    >    +		ksi->ksni_netmask = ifaces.li_netmask[i];
    >    +		strlcpy(ksi->ksni_name, ifaces.li_name[i],
    >    +			sizeof(ksi->ksni_name));
    >     	}
    > 
    >     	/* call it before add it to ksocknal_data.ksnd_nets */
    >    diff --git a/lnet/lnet/config.c b/lnet/lnet/config.c
    >    index 12b2442..666f0f0 100644
    >    --- a/lnet/lnet/config.c
    >    +++ b/lnet/lnet/config.c
    >    @@ -1611,34 +1611,28 @@ lnet_match_networks (char **networksp, char *ip2nets, __u32 *ipaddrs, int nip)
    >     	return count;
    >     }
    > 
    >    -static void
    >    -lnet_ipaddr_free_enumeration(__u32 *ipaddrs, int nip)
    >    -{
    >    -	LIBCFS_FREE(ipaddrs, nip * sizeof(*ipaddrs));
    >    -}
    >    -
    >    -static int
    >    -lnet_ipaddr_enumerate(u32 **ipaddrsp)
    >    +int lnet_inet_enumerate(struct lnet_ni *ni, struct lnet_inetdev *ifaces,
    >    +			char *iname, int ifa_done)
    >     {
    >     	struct net_device *dev;
    >    -	u32 *ipaddrs;
    >    -	int nalloc = 64;
    >    -	int nip = 0;
    >    -
    >    -	LIBCFS_ALLOC(ipaddrs, nalloc * sizeof(*ipaddrs));
    >    -	if (!ipaddrs) {
    >    -		CERROR("Can't allocate ipaddrs[%d]\n", nalloc);
    >    -		return -ENOMEM;
    >    -	}
    >    +	int skip = 0;
    >    +	int rc = 0;
    > 
    >     	rtnl_lock();
    >     	for_each_netdev(&init_net, dev) {
    >    +		/* The iname specified by an user land configuration can
    >    +		 * map to an ifa_label so always treat iname as an ifa_label.
    >    +		 * If iname is NULL then fall back to the net device name.
    >    +		 */
    >    +		const char *name = iname ? iname : dev->name;
    >     		struct in_device *in_dev;
    > 
    >    -		if (strcmp(dev->name, "lo") == 0)
    >    +		ifaces->li_flags = dev_get_flags(dev);
    >    +
    >    +		if (ifaces->li_flags & IFF_LOOPBACK) /* skip the loopback IF */
    >     			continue;
    > 
    >    -		if (!(dev_get_flags(dev) & IFF_UP)) {
    >    +		if (!(ifaces->li_flags & IFF_UP)) {
    >     			CWARN("Ignoring interface %s: it's down\n", dev->name);
    >     			continue;
    >     		}
    >    @@ -1649,65 +1643,109 @@ lnet_ipaddr_enumerate(u32 **ipaddrsp)
    >     			continue;
    >     		}
    > 
    >    -		if (nip >= nalloc) {
    >    -			u32 *ipaddrs2;
    >    +		if (ni && ni->ni_dev_cpt != CFS_CPT_ANY) {
    >    +			int node_id = dev_to_node(&dev->dev);
    >    +			int cpt = cfs_cpt_of_node(lnet_cpt_table(), node_id);
    > 
    >    -			nalloc += nalloc;
    >    -			ipaddrs2 = krealloc(ipaddrs, nalloc * sizeof(*ipaddrs2),
    >    -					    GFP_KERNEL);
    >    -			if (!ipaddrs2) {
    >    -				kfree(ipaddrs);
    >    -				CERROR("Can't allocate ipaddrs[%d]\n", nip);
    >    -				return -ENOMEM;
    >    +			if (ni->ni_dev_cpt != cpt &&
    >    +			    ifaces->li_interfaces > 0) {
    >    +				ni->ni_dev_cpt = CFS_CPT_ANY;
    >    +				CWARN("Not all the network interfaces belong to the same CPT\n");
    >    +			} else {
    >    +				ni->ni_dev_cpt = cpt;
    >     			}
    >    -			ipaddrs = ipaddrs2;
    >     		}
    > 
    >    -		for_primary_ifa(in_dev)
    >    -			if (strcmp(ifa->ifa_label, dev->name) == 0) {
    >    -				ipaddrs[nip++] = ifa->ifa_local;
    >    -				break;
    >    +		for_ifa(in_dev)
    >    +			if (strcmp(name, ifa->ifa_label) == 0) {
    >    +				int idx = ifaces->li_interfaces;
    >    +
    >    +				if (idx >= ARRAY_SIZE(ifaces->li_name))
    >    +					return -E2BIG;
    >    +
    >    +				if (skip++ < ifa_done)
    >    +					continue;
    >    +
    >    +				ifaces->li_ipaddr[idx] = ntohl(ifa->ifa_local);
    >    +				ifaces->li_netmask[idx] = ifa->ifa_mask;
    >    +				strlcpy(ifaces->li_name[idx], name,
    >    +					sizeof(ifaces->li_name[idx]));
    >    +				ifaces->li_interfaces++;
    >    +				goto unlock_rtnl;
    >     			}
    >     		endfor_ifa(in_dev);
    >     	}
    >    +unlock_rtnl:
    >     	rtnl_unlock();
    > 
    >    -	*ipaddrsp = ipaddrs;
    >    -	return nip;
    >    +	if (ifaces->li_interfaces == 0) {
    >    +		CERROR("Can't find any usable interfaces\n");
    >    +		rc = -ENOENT;
    >    +	}
    >    +
    >    +	return rc;
    >     }
    >    +EXPORT_SYMBOL(lnet_inet_enumerate);
    > 
    >     int
    >    -lnet_parse_ip2nets (char **networksp, char *ip2nets)
    >    +lnet_parse_ip2nets(char **networksp, char *ip2nets)
    >     {
    >    -	__u32	  *ipaddrs = NULL;
    >    -	int	   nip = lnet_ipaddr_enumerate(&ipaddrs);
    >    -	int	   rc;
    >    -
    >    -	if (nip < 0) {
    >    -		LCONSOLE_ERROR_MSG(0x117, "Error %d enumerating local IP "
    >    -				   "interfaces for ip2nets to match\n", nip);
    >    -		return nip;
    >    -	}
    >    +	struct lnet_inetdev ifaces;
    >    +	u32 *ipaddrs = NULL;
    >    +	int nalloc = 0;
    >    +	int nip = 0;
    >    +	int rc;
    > 
    >    -	if (nip == 0) {
    >    -		LCONSOLE_ERROR_MSG(0x118, "No local IP interfaces "
    >    -				   "for ip2nets to match\n");
    >    -		return -ENOENT;
    >    -	}
    >    +realloc:
    >    +	ifaces.li_interfaces = 0;
    >    +	rc = lnet_inet_enumerate(NULL, &ifaces, NULL, nip);
    >    +	if (rc < 0) {
    >    +		/* Handle edge case where we nip is muliple of
    >    +		 * LNET_INTERFACES_NUM and no more devices are
    >    +		 * detected.
    >    +		 */
    >    +		if (rc == -ENOENT && nip > 0)
    >    +			goto match_networks;
    > 
    >    -	rc = lnet_match_networks(networksp, ip2nets, ipaddrs, nip);
    >    -	lnet_ipaddr_free_enumeration(ipaddrs, nip);
    >    +		LCONSOLE_ERROR_MSG(0x117,
    >    +				   "Error %d enumerating local IP interfaces for ip2nets to match\n",
    >    +				   rc);
    >    +		goto out_free_addrs;
    >    +	} else {
    >    +		u32 *ipaddrs2;
    >    +		int i;
    >    +
    >    +		nalloc += ifaces.li_interfaces;
    >    +		ipaddrs2 = krealloc(ipaddrs, nalloc * sizeof(*ipaddrs),
    >    +				    GFP_KERNEL);
    >    +		if (!ipaddrs2) {
    >    +			CERROR("Can't allocate ipaddrs[%d]\n", nalloc);
    >    +			goto out_free_addrs;
    >    +		}
    >    +		ipaddrs = ipaddrs2;
    > 
    >    +		for (i = 0; i < ifaces.li_interfaces; i++) {
    >    +			memcpy(ipaddrs + nip, ifaces.li_ipaddr,
    >    +			       sizeof(*ipaddrs) * LNET_INTERFACES_NUM);
    >    +		}
    >    +
    >    +		/* Maybe more ? */
    >    +		if (ifaces.li_interfaces == LNET_INTERFACES_NUM) {
    >    +			nip += LNET_INTERFACES_NUM;
    >    +			goto realloc;
    >    +		}
    >    +	}
    >    +match_networks:
    >    +	rc = lnet_match_networks(networksp, ip2nets, ipaddrs, nip);
    >     	if (rc < 0) {
    >     		LCONSOLE_ERROR_MSG(0x119, "Error %d parsing ip2nets\n", rc);
    >     		return rc;
    >    -	}
    >    -
    >    -	if (rc == 0) {
    >    +	} else if (rc == 0) {
    >     		LCONSOLE_ERROR_MSG(0x11a, "ip2nets does not match "
    >     				   "any local IP interfaces\n");
    >     		return -ENOENT;
    >     	}
    >    -
    >    -	return 0;
    >    +out_free_addrs:
    >    +	LIBCFS_FREE(ipaddrs, nip * sizeof(*ipaddrs));
    >    +	return rc;
    >     }
    >    -- 
    >    1.8.3.1
    > 
    > 
    > 
    > _______________________________________________
    > lustre-devel mailing list
    > lustre-devel at lists.lustre.org
    > http://lists.lustre.org/listinfo.cgi/lustre-devel-lustre.org
    
    Cheers, Andreas
    --
    Andreas Dilger
    Principal Lustre Architect
    Whamcloud
    
    

^ permalink raw reply	[flat|nested] 9+ messages in thread

* [lustre-devel] lnet ip2nets option broken in master?
@ 2019-05-24 16:28 Degremont, Aurelien
  0 siblings, 0 replies; 9+ messages in thread
From: Degremont, Aurelien @ 2019-05-24 16:28 UTC (permalink / raw)
  To: lustre-devel

Hi all,

I'm doing several tests with LNET and I realized lnet module option 'ip2nets' does not work anymore.
I git-bisected the regression down to:

commit f5991afd8779fe747778e28e998277a10242a57d
Author: NeilBrown <neilb@suse.com>
Date:   Mon Jan 7 14:23:19 2019 -0500

    LU-11838 lnet: change lnet_ipaddr_enumerate() to use for_each_netdev()


Am I doing something wrong? Is that already known and there is some patchs around for it?

Funny thing is that the normal way to use it does not work, but if I specify IP address in the reverse order, it works. (Could be just a side effect/red herring)

Ie: ip2nets="tcp2(eth0) 172.32.47.137".  -> ERROR (correct IP)
ip2net="tcp2(eth0) 137.47.32.172" -> OK

I was not able to understand the bug.

If it makes sense, I can open a ticket.

Aur?lien

^ permalink raw reply	[flat|nested] 9+ messages in thread

end of thread, other threads:[~2019-06-11  9:02 UTC | newest]

Thread overview: 9+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2019-05-25 14:33 [lustre-devel] lnet ip2nets option broken in master? Chris Horn
2019-05-27  8:48 ` Degremont, Aurelien
2019-05-27 18:03   ` Andreas Dilger
2019-05-28 13:05     ` Degremont, Aurelien
2019-05-28 13:13   ` James Simmons
2019-05-28 13:57     ` Degremont, Aurelien
2019-06-11  6:27       ` Andreas Dilger
2019-06-11  9:02         ` Degremont, Aurelien
  -- strict thread matches above, loose matches on Subject: below --
2019-05-24 16:28 Degremont, Aurelien

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.