X-Git-Url: https://git.whamcloud.com/?a=blobdiff_plain;f=lnet%2Flnet%2Fconfig.c;h=8606f481e88fb95f07e3800e6ed35e3ebdcb2d53;hb=416e67222b769df490a8be034ef987a596dd8dff;hp=15f80bddfe80915d2275aae66d5a7ba5ecabe715;hpb=1d80e9debf992a41b2caf285964fa7af4b1c1246;p=fs%2Flustre-release.git diff --git a/lnet/lnet/config.c b/lnet/lnet/config.c index 15f80bd..8606f48 100644 --- a/lnet/lnet/config.c +++ b/lnet/lnet/config.c @@ -381,7 +381,6 @@ lnet_net_alloc(__u32 net_id, struct list_head *net_list) net->net_id = net_id; net->net_last_alive = ktime_get_real_seconds(); - net->net_state = LNET_NET_STATE_INIT; /* initialize global paramters to undefiend */ net->net_tunables.lct_peer_timeout = -1; @@ -480,10 +479,10 @@ lnet_ni_alloc_common(struct lnet_net *net, char *iface) ni->ni_nid = LNET_MKNID(net->net_id, 0); /* Store net namespace in which current ni is being created */ - if (current->nsproxy->net_ns != NULL) + if (current->nsproxy && current->nsproxy->net_ns) ni->ni_net_ns = get_net(current->nsproxy->net_ns); else - ni->ni_net_ns = NULL; + ni->ni_net_ns = get_net(&init_net); ni->ni_state = LNET_NI_STATE_INIT; list_add_tail(&ni->ni_netlist, &net->net_ni_added); @@ -1313,7 +1312,7 @@ lnet_parse_routes (char *routes, int *im_a_router) static int lnet_match_network_token(char *token, int len, __u32 *ipaddrs, int nip) { - struct list_head list = LIST_HEAD_INIT(list); + LIST_HEAD(list); int rc; int i; @@ -1575,12 +1574,11 @@ lnet_match_networks (char **networksp, char *ip2nets, __u32 *ipaddrs, int nip) list_for_each_safe(t, t2, ¤t_nets) { tb = list_entry(t, struct lnet_text_buf, ltb_list); - list_del(&tb->ltb_list); - list_add_tail(&tb->ltb_list, &matched_nets); + list_move_tail(&tb->ltb_list, &matched_nets); - len += snprintf(networks + len, sizeof(networks) - len, - "%s%s", (len == 0) ? "" : ",", - tb->ltb_text); + len += scnprintf(networks + len, sizeof(networks) - len, + "%s%s", (len == 0) ? "" : ",", + tb->ltb_text); if (len >= sizeof(networks)) { CERROR("Too many matched networks\n"); @@ -1604,104 +1602,139 @@ lnet_match_networks (char **networksp, char *ip2nets, __u32 *ipaddrs, int nip) *networksp = networks; 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) +/* + * kernel 5.3: commit ef11db3310e272d3d8dbe8739e0770820dd20e52 + * added in_dev_for_each_ifa_rtnl and in_dev_for_each_ifa_rcu + * and removed for_ifa and endfor_ifa. + * Use the _rntl variant as the current locking is rtnl. + */ +#ifdef in_dev_for_each_ifa_rtnl +#define DECLARE_CONST_IN_IFADDR(ifa) const struct in_ifaddr *ifa +#define endfor_ifa(in_dev) +#else +#define DECLARE_CONST_IN_IFADDR(ifa) +#define in_dev_for_each_ifa_rtnl(ifa, in_dev) for_ifa((in_dev)) +#endif + +int lnet_inet_enumerate(struct lnet_inetdev **dev_list, struct net *ns) { + struct lnet_inetdev *ifaces = NULL; struct net_device *dev; - u32 *ipaddrs; - int nalloc = 64; + int nalloc = 0; int nip = 0; - - LIBCFS_ALLOC(ipaddrs, nalloc * sizeof(*ipaddrs)); - if (!ipaddrs) { - CERROR("Can't allocate ipaddrs[%d]\n", nalloc); - return -ENOMEM; - } + DECLARE_CONST_IN_IFADDR(ifa); rtnl_lock(); - for_each_netdev(&init_net, dev) { + for_each_netdev(ns, dev) { + int flags = dev_get_flags(dev); struct in_device *in_dev; + int node_id; + int cpt; - if (strcmp(dev->name, "lo") == 0) + if (flags & IFF_LOOPBACK) /* skip the loopback IF */ continue; - if (!(dev_get_flags(dev) & IFF_UP)) { - CWARN("Ignoring interface %s: it's down\n", dev->name); + if (!(flags & IFF_UP)) { + CWARN("lnet: Ignoring interface %s: it'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); + CWARN("lnet: Interface %s has no IPv4 status.\n", + dev->name); continue; } - if (nip >= nalloc) { - u32 *ipaddrs2; - - nalloc += nalloc; - ipaddrs2 = krealloc(ipaddrs, nalloc * sizeof(*ipaddrs2), - GFP_KERNEL); - if (!ipaddrs2) { - kfree(ipaddrs); - CERROR("Can't allocate ipaddrs[%d]\n", nip); - return -ENOMEM; + node_id = dev_to_node(&dev->dev); + cpt = cfs_cpt_of_node(lnet_cpt_table(), node_id); + + in_dev_for_each_ifa_rtnl(ifa, in_dev) { + if (nip >= nalloc) { + struct lnet_inetdev *tmp; + + nalloc += LNET_INTERFACES_NUM; + tmp = krealloc(ifaces, nalloc * sizeof(*tmp), + GFP_KERNEL); + if (!tmp) { + kfree(ifaces); + ifaces = NULL; + nip = -ENOMEM; + goto unlock_rtnl; + } + ifaces = tmp; } - ipaddrs = ipaddrs2; - } - for_primary_ifa(in_dev) - if (strcmp(ifa->ifa_label, dev->name) == 0) { - ipaddrs[nip++] = ifa->ifa_local; - break; - } + ifaces[nip].li_cpt = cpt; + ifaces[nip].li_flags = flags; + ifaces[nip].li_ipaddr = ntohl(ifa->ifa_local); + ifaces[nip].li_netmask = ntohl(ifa->ifa_mask); + strlcpy(ifaces[nip].li_name, ifa->ifa_label, + sizeof(ifaces[nip].li_name)); + nip++; + } endfor_ifa(in_dev); } +unlock_rtnl: rtnl_unlock(); - *ipaddrsp = ipaddrs; + if (nip == 0) { + CERROR("lnet: Can't find any usable interfaces, rc = -ENOENT\n"); + nip = -ENOENT; + } + + *dev_list = ifaces; return nip; } +EXPORT_SYMBOL(lnet_inet_enumerate); int lnet_parse_ip2nets (char **networksp, char *ip2nets) { + struct lnet_inetdev *ifaces = NULL; __u32 *ipaddrs = NULL; - int nip = lnet_ipaddr_enumerate(&ipaddrs); + int nip; int rc; + int i; + if (current->nsproxy && current->nsproxy->net_ns) + nip = lnet_inet_enumerate(&ifaces, current->nsproxy->net_ns); + else + nip = lnet_inet_enumerate(&ifaces, &init_net); if (nip < 0) { - LCONSOLE_ERROR_MSG(0x117, "Error %d enumerating local IP " - "interfaces for ip2nets to match\n", nip); + if (nip != -ENOENT) { + LCONSOLE_ERROR_MSG(0x117, + "Error %d enumerating local IP interfaces for ip2nets to match\n", + nip); + } else { + LCONSOLE_ERROR_MSG(0x118, + "No local IP interfaces for ip2nets to match\n"); + } return nip; } - if (nip == 0) { - LCONSOLE_ERROR_MSG(0x118, "No local IP interfaces " - "for ip2nets to match\n"); - return -ENOENT; + LIBCFS_ALLOC(ipaddrs, nip * sizeof(*ipaddrs)); + if (!ipaddrs) { + rc = -ENOMEM; + CERROR("lnet: Can't allocate ipaddrs[%d], rc = %d\n", + nip, rc); + goto out_free_addrs; } - rc = lnet_match_networks(networksp, ip2nets, ipaddrs, nip); - lnet_ipaddr_free_enumeration(ipaddrs, nip); + for (i = 0; i < nip; i++) + ipaddrs[i] = ifaces[i].li_ipaddr; + 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; + rc = -ENOENT; } - - return 0; + LIBCFS_FREE(ipaddrs, nip * sizeof(*ipaddrs)); +out_free_addrs: + kfree(ifaces); + return rc > 0 ? 0 : rc; }