From: eeb Date: Fri, 6 May 2005 14:25:14 +0000 (+0000) Subject: * placeholder (digging out IP interface info) X-Git-Tag: v1_7_100~1^25~6^2~268 X-Git-Url: https://git.whamcloud.com/?a=commitdiff_plain;h=4a52096fb342cff0d333b06c66b3f411881be0cb;p=fs%2Flustre-release.git * placeholder (digging out IP interface info) --- diff --git a/lnet/include/lnet/lib-types.h b/lnet/include/lnet/lib-types.h index a6e9ca7..273ffb6 100644 --- a/lnet/include/lnet/lib-types.h +++ b/lnet/include/lnet/lib-types.h @@ -313,7 +313,7 @@ typedef struct ptl_nal } ptl_nal_t; -#define PTL_MAX_INTERFACES 8 +#define PTL_MAX_INTERFACES 16 typedef struct ptl_ni { struct list_head ni_list; /* chain on apini_nis */ @@ -377,6 +377,9 @@ typedef struct struct list_head *apini_lh_hash_table; /* all extant lib handles, this interface */ __u64 apini_next_object_cookie; /* cookie generator */ __u64 apini_interface_cookie; /* uniquely identifies this ni in this epoch */ + + char *apini_network_tokens; /* space for network names */ + int apini_network_tokens_nob; struct list_head apini_test_peers; diff --git a/lnet/klnds/socklnd/socklnd.c b/lnet/klnds/socklnd/socklnd.c index 46f31d9..d6f6180 100644 --- a/lnet/klnds/socklnd/socklnd.c +++ b/lnet/klnds/socklnd/socklnd.c @@ -40,25 +40,6 @@ ptl_nal_t ksocknal_nal = { ksock_nal_data_t ksocknal_data; -int -ksocknal_set_mynid(ptl_nid_t nid) -{ - ptl_ni_t *ni = ksocknal_data.ksnd_ni; - - /* FIXME: we have to do this because we call lib_init() at module - * insertion time, which is before we have 'mynid' available. lib_init - * sets the NAL's nid, which it uses to tell other nodes where packets - * are coming from. This is not a very graceful solution to this - * problem. */ - - CDEBUG(D_IOCTL, "setting mynid to %s (old nid=%s)\n", - libcfs_nid2str(nid), libcfs_nid2str(ni->ni_nid)); - - LASSERT (PTL_NIDNET(nid) == PTL_NIDNET(ni->ni_nid)); - ni->ni_nid = nid; - return (0); -} - ksock_interface_t * ksocknal_ip2iface(__u32 ip) { @@ -66,7 +47,7 @@ ksocknal_ip2iface(__u32 ip) ksock_interface_t *iface; for (i = 0; i < ksocknal_data.ksnd_ninterfaces; i++) { - LASSERT(i < SOCKNAL_MAX_INTERFACES); + LASSERT(i < PTL_MAX_INTERFACES); iface = &ksocknal_data.ksnd_interfaces[i]; if (iface->ksni_ipaddr == ip) @@ -201,7 +182,7 @@ ksocknal_unlink_peer_locked (ksock_peer_t *peer) __u32 ip; for (i = 0; i < peer->ksnp_n_passive_ips; i++) { - LASSERT (i < SOCKNAL_MAX_INTERFACES); + LASSERT (i < PTL_MAX_INTERFACES); ip = peer->ksnp_passive_ips[i]; ksocknal_ip2iface(ip)->ksni_npeers--; @@ -641,7 +622,7 @@ ksocknal_local_ipvec (__u32 *ipaddrs) nip = ksocknal_data.ksnd_ninterfaces; for (i = 0; i < nip; i++) { - LASSERT (i < SOCKNAL_MAX_INTERFACES); + LASSERT (i < PTL_MAX_INTERFACES); ipaddrs[i] = ksocknal_data.ksnd_interfaces[i].ksni_ipaddr; LASSERT (ipaddrs[i] != 0); @@ -710,8 +691,8 @@ ksocknal_select_ips(ksock_peer_t *peer, __u32 *peerips, int n_peerips) write_lock_irqsave(global_lock, flags); - LASSERT (n_peerips <= SOCKNAL_MAX_INTERFACES); - LASSERT (ksocknal_data.ksnd_ninterfaces <= SOCKNAL_MAX_INTERFACES); + LASSERT (n_peerips <= PTL_MAX_INTERFACES); + LASSERT (ksocknal_data.ksnd_ninterfaces <= PTL_MAX_INTERFACES); n_ips = MIN(n_peerips, ksocknal_data.ksnd_ninterfaces); @@ -810,7 +791,7 @@ ksocknal_create_routes(ksock_peer_t *peer, int port, write_lock_irqsave(global_lock, flags); - LASSERT (npeer_ipaddrs <= SOCKNAL_MAX_INTERFACES); + LASSERT (npeer_ipaddrs <= PTL_MAX_INTERFACES); for (i = 0; i < npeer_ipaddrs; i++) { if (newroute != NULL) { @@ -842,7 +823,7 @@ ksocknal_create_routes(ksock_peer_t *peer, int port, best_nroutes = 0; best_netmatch = 0; - LASSERT (ksocknal_data.ksnd_ninterfaces <= SOCKNAL_MAX_INTERFACES); + LASSERT (ksocknal_data.ksnd_ninterfaces <= PTL_MAX_INTERFACES); /* Select interface to connect from */ for (j = 0; j < ksocknal_data.ksnd_ninterfaces; j++) { @@ -993,7 +974,7 @@ ksocknal_create_conn (ksock_route_t *route, struct socket *sock, int type) { int passive = (type == SOCKNAL_CONN_NONE); rwlock_t *global_lock = &ksocknal_data.ksnd_global_lock; - __u32 ipaddrs[SOCKNAL_MAX_INTERFACES]; + __u32 ipaddrs[PTL_MAX_INTERFACES]; int nipaddrs; ptl_nid_t nid; struct list_head *tmp; @@ -1249,7 +1230,6 @@ ksocknal_close_conn_locked (ksock_conn_t *conn, int error) LASSERT (peer->ksnp_error == 0); LASSERT (!conn->ksnc_closing); conn->ksnc_closing = 1; - atomic_inc (&ksocknal_data.ksnd_nclosing_conns); /* ksnd_deathrow_conns takes over peer's ref */ list_del (&conn->ksnc_list); @@ -1424,7 +1404,6 @@ ksocknal_destroy_conn (ksock_conn_t *conn) ksocknal_peer_decref(conn->ksnc_peer); PORTAL_FREE (conn, sizeof (*conn)); - atomic_dec (&ksocknal_data.ksnd_nclosing_conns); } int @@ -1659,7 +1638,7 @@ ksocknal_add_interface(__u32 ipaddress, __u32 netmask) if (iface != NULL) { /* silently ignore dups */ rc = 0; - } else if (ksocknal_data.ksnd_ninterfaces == SOCKNAL_MAX_INTERFACES) { + } else if (ksocknal_data.ksnd_ninterfaces == PTL_MAX_INTERFACES) { rc = -ENOSPC; } else { iface = &ksocknal_data.ksnd_interfaces[ksocknal_data.ksnd_ninterfaces++]; @@ -1807,17 +1786,16 @@ ksocknal_ctl(ptl_ni_t *ni, unsigned int cmd, void *arg) } read_unlock (&ksocknal_data.ksnd_global_lock); - break; - } - case IOC_PORTAL_ADD_INTERFACE: { - rc = ksocknal_add_interface(data->ioc_u32[0], /* IP address */ - data->ioc_u32[1]); /* net mask */ - break; - } - case IOC_PORTAL_DEL_INTERFACE: { - rc = ksocknal_del_interface(data->ioc_u32[0]); /* IP address */ - break; + return rc; } + + case IOC_PORTAL_ADD_INTERFACE: + return ksocknal_add_interface(data->ioc_u32[0], /* IP address */ + data->ioc_u32[1]); /* net mask */ + + case IOC_PORTAL_DEL_INTERFACE: + return ksocknal_del_interface(data->ioc_u32[0]); /* IP address */ + case IOC_PORTAL_GET_PEER: { ptl_nid_t nid = 0; __u32 myip = 0; @@ -1835,65 +1813,65 @@ ksocknal_ctl(ptl_ni_t *ni, unsigned int cmd, void *arg) data->ioc_u32[1] = port; data->ioc_u32[2] = myip; data->ioc_u32[3] = conn_count; - break; - } - case IOC_PORTAL_ADD_PEER: { - rc = ksocknal_add_peer (data->ioc_nid, - data->ioc_u32[0], /* IP */ - data->ioc_u32[1]); /* port */ - break; - } - case IOC_PORTAL_DEL_PEER: { - rc = ksocknal_del_peer (data->ioc_nid, - data->ioc_u32[0]); /* IP */ - break; + return 0; } + + case IOC_PORTAL_ADD_PEER: + return ksocknal_add_peer (data->ioc_nid, + data->ioc_u32[0], /* IP */ + data->ioc_u32[1]); /* port */ + + case IOC_PORTAL_DEL_PEER: + return ksocknal_del_peer (data->ioc_nid, + data->ioc_u32[0]); /* IP */ + case IOC_PORTAL_GET_CONN: { + int txmem; + int rxmem; + int nagle; ksock_conn_t *conn = ksocknal_get_conn_by_idx (data->ioc_count); if (conn == NULL) - rc = -ENOENT; - else { - int txmem; - int rxmem; - int nagle; + return -ENOENT; + + ksocknal_lib_get_conn_tunables(conn, &txmem, &rxmem, &nagle); + + data->ioc_count = txmem; + data->ioc_nid = conn->ksnc_peer->ksnp_nid; + data->ioc_flags = nagle; + data->ioc_u32[0] = conn->ksnc_ipaddr; + data->ioc_u32[1] = conn->ksnc_port; + data->ioc_u32[2] = conn->ksnc_myipaddr; + data->ioc_u32[3] = conn->ksnc_type; + data->ioc_u32[4] = conn->ksnc_scheduler - + ksocknal_data.ksnd_schedulers; + data->ioc_u32[5] = rxmem; + ksocknal_conn_decref(conn); + return 0; + } - ksocknal_lib_get_conn_tunables(conn, &txmem, &rxmem, &nagle); + case IOC_PORTAL_CLOSE_CONNECTION: + return ksocknal_close_matching_conns (data->ioc_nid, + data->ioc_u32[0]); + + case IOC_PORTAL_REGISTER_MYNID: + if (data->ioc_nid == ni->ni_nid) + return 0; + + LASSERT (PTL_NIDNET(data->ioc_nid) == PTL_NIDNET(ni->ni_nid)); + + CERROR("obsolete IOC_PORTAL_REGISTER_MYNID for %s(%s)\n", + libcfs_nid2str(data->ioc_nid), + libcfs_nid2str(ni->ni_nid)); + return 0; + + case IOC_PORTAL_PUSH_CONNECTION: + return ksocknal_push (data->ioc_nid); - rc = 0; - data->ioc_count = txmem; - data->ioc_nid = conn->ksnc_peer->ksnp_nid; - data->ioc_flags = nagle; - data->ioc_u32[0] = conn->ksnc_ipaddr; - data->ioc_u32[1] = conn->ksnc_port; - data->ioc_u32[2] = conn->ksnc_myipaddr; - data->ioc_u32[3] = conn->ksnc_type; - data->ioc_u32[4] = conn->ksnc_scheduler - - ksocknal_data.ksnd_schedulers; - data->ioc_u32[5] = rxmem; - ksocknal_conn_decref(conn); - } - break; - } - case IOC_PORTAL_CLOSE_CONNECTION: { - rc = ksocknal_close_matching_conns (data->ioc_nid, - data->ioc_u32[0]); - break; - } - case IOC_PORTAL_REGISTER_MYNID: { - rc = ksocknal_set_mynid (data->ioc_nid); - break; - } - case IOC_PORTAL_PUSH_CONNECTION: { - rc = ksocknal_push (data->ioc_nid); - break; - } default: - rc = -EINVAL; - break; + return -EINVAL; } - - return rc; + /* not reached */ } void @@ -2071,11 +2049,6 @@ ksocknal_startup (ptl_ni_t *ni) return PTL_FAIL; } - if (ni->ni_interfaces[0] != NULL) { - CERROR("Explicit interface config not supported\n"); - return PTL_FAIL; - } - memset (&ksocknal_data, 0, sizeof (ksocknal_data)); /* zero pointers */ ksocknal_data.ksnd_ni = ni; /* temp hack */ @@ -2087,7 +2060,7 @@ ksocknal_startup (ptl_ni_t *ni) PORTAL_ALLOC (ksocknal_data.ksnd_peers, sizeof (struct list_head) * ksocknal_data.ksnd_peer_hash_size); if (ksocknal_data.ksnd_peers == NULL) - return (-ENOMEM); + return PTL_FAIL; for (i = 0; i < ksocknal_data.ksnd_peer_hash_size; i++) CFS_INIT_LIST_HEAD(&ksocknal_data.ksnd_peers[i]); @@ -2127,10 +2100,8 @@ ksocknal_startup (ptl_ni_t *ni) ksocknal_data.ksnd_nschedulers = ksocknal_nsched(); PORTAL_ALLOC(ksocknal_data.ksnd_schedulers, sizeof(ksock_sched_t) * ksocknal_data.ksnd_nschedulers); - if (ksocknal_data.ksnd_schedulers == NULL) { - ksocknal_shutdown (ni); - return (-ENOMEM); - } + if (ksocknal_data.ksnd_schedulers == NULL) + goto failed; for (i = 0; i < ksocknal_data.ksnd_nschedulers; i++) { ksock_sched_t *kss = &ksocknal_data.ksnd_schedulers[i]; @@ -2150,8 +2121,7 @@ ksocknal_startup (ptl_ni_t *ni) if (rc != 0) { CERROR("Can't spawn socknal scheduler[%d]: %d\n", i, rc); - ksocknal_shutdown (ni); - return (rc); + goto failed; } } @@ -2159,16 +2129,14 @@ ksocknal_startup (ptl_ni_t *ni) rc = ksocknal_thread_start (ksocknal_connd, (void *)((long)i)); if (rc != 0) { CERROR("Can't spawn socknal connd: %d\n", rc); - ksocknal_shutdown (ni); - return (rc); + goto failed; } } rc = ksocknal_thread_start (ksocknal_reaper, NULL); if (rc != 0) { CERROR ("Can't spawn socknal reaper: %d\n", rc); - ksocknal_shutdown (ni); - return (rc); + goto failed; } if (kpr_forwarding()) { @@ -2187,20 +2155,16 @@ ksocknal_startup (ptl_ni_t *ni) PORTAL_ALLOC(fmb, offsetof(ksock_fmb_t, fmb_kiov[pool->fmp_buff_pages])); - if (fmb == NULL) { - ksocknal_shutdown(ni); - return (-ENOMEM); - } + if (fmb == NULL) + goto failed; fmb->fmb_pool = pool; for (j = 0; j < pool->fmp_buff_pages; j++) { fmb->fmb_kiov[j].kiov_page = cfs_alloc_page(CFS_ALLOC_STD); - if (fmb->fmb_kiov[j].kiov_page == NULL) { - ksocknal_shutdown (ni); - return (-ENOMEM); - } + if (fmb->fmb_kiov[j].kiov_page == NULL) + goto failed; LASSERT(cfs_page_address(fmb->fmb_kiov[j].kiov_page) != NULL); } @@ -2212,10 +2176,35 @@ ksocknal_startup (ptl_ni_t *ni) rc = ksocknal_start_listener(); if (rc != 0) { CERROR("Can't start listener: %d\n", rc); - ksocknal_shutdown(ni); - return rc; + goto failed; } + if (ni->ni_interfaces[0] == NULL) { + rc = ksocknal_lib_enumerate_ifs(ksocknal_data.ksnd_interfaces, + PTL_MAX_INTERFACES); + if (rc != 0) + goto failed; + + if (rc == 0) { + CERROR("Can't find any interfaces\n"); + goto failed; + } + } else { + for (i = 0; i < PTL_MAX_INTERFACES; i++) { + if (ni->ni_interfaces[i] == NULL) + break; + + rc = ksocknal_lib_init_if(&ksocknal_data.ksnd_interfaces[i], + ni->ni_interfaces[i]); + if (rc != 0) + goto failed; + } + } + + ni->ni_nid = PTL_MKNID(PTL_NIDNET(ni->ni_nid), + ksocknal_data.ksnd_interfaces[0].ksni_ipaddr); + CDEBUG(D_WARNING, "Set NID to %s\n", libcfs_nid2str(ni->ni_nid)); + /* flag everything initialised */ ksocknal_data.ksnd_init = SOCKNAL_INIT_ALL; @@ -2223,7 +2212,11 @@ ksocknal_startup (ptl_ni_t *ni) "(initial mem %d, incarnation "LPD64")\n", pkmem, ksocknal_data.ksnd_incarnation); - return (0); + return PTL_OK; + + failed: + ksocknal_shutdown(ni); + return PTL_FAIL; } void __exit diff --git a/lnet/klnds/socklnd/socklnd.h b/lnet/klnds/socklnd/socklnd.h index ee7bba4..af55041 100644 --- a/lnet/klnds/socklnd/socklnd.h +++ b/lnet/klnds/socklnd/socklnd.h @@ -76,8 +76,6 @@ #define SOCKNAL_RESCHED 100 /* # scheduler loops before reschedule */ #define SOCKNAL_ENOMEM_RETRY CFS_MIN_DELAY /* jiffies between retries */ -#define SOCKNAL_MAX_INTERFACES 16 /* Largest number of interfaces we bind */ - #define SOCKNAL_ROUND_ROBIN 0 /* round robin / load balance */ #define SOCKNAL_SINGLE_FRAG_TX 0 /* disable multi-fragment sends */ @@ -120,12 +118,13 @@ typedef struct int ksni_sched:6; /* which scheduler (assumes < 64) */ } ksock_irqinfo_t; -typedef struct +typedef struct /* in-use interface */ { __u32 ksni_ipaddr; /* interface's IP address */ __u32 ksni_netmask; /* interface's network mask */ int ksni_nroutes; /* # routes using (active) */ int ksni_npeers; /* # peers using (passive) */ + char ksni_name[16]; /* interface name */ } ksock_interface_t; typedef struct @@ -205,7 +204,7 @@ typedef struct ptl_ni_t *ksnd_ni; /* NI instance (tmp hack) */ int ksnd_ninterfaces; - ksock_interface_t ksnd_interfaces[SOCKNAL_MAX_INTERFACES]; /* published interfaces */ + ksock_interface_t ksnd_interfaces[PTL_MAX_INTERFACES]; /* active interfaces */ } ksock_nal_data_t; #define SOCKNAL_INIT_NOTHING 0 @@ -382,7 +381,7 @@ typedef struct ksock_peer struct list_head ksnp_tx_queue; /* waiting packets */ cfs_time_t ksnp_last_alive; /* when (in jiffies) I was last alive */ int ksnp_n_passive_ips; /* # of... */ - __u32 ksnp_passive_ips[SOCKNAL_MAX_INTERFACES]; /* preferred local interfaces */ + __u32 ksnp_passive_ips[PTL_MAX_INTERFACES]; /* preferred local interfaces */ } ksock_peer_t; typedef struct ksock_connreq @@ -561,3 +560,7 @@ extern void ksocknal_lib_abort_accept(struct socket *sock); extern int ksocknal_lib_tunables_init(void); extern void ksocknal_lib_tunables_fini(void); + +extern int ksocknal_lib_init_if (ksock_interface_t *iface, char *name); +extern int ksocknal_lib_enumerate_ifs (ksock_interface_t *ifs, int nifs); + diff --git a/lnet/klnds/socklnd/socklnd_cb.c b/lnet/klnds/socklnd/socklnd_cb.c index 8beaa7c..7a1be2b 100644 --- a/lnet/klnds/socklnd/socklnd_cb.c +++ b/lnet/klnds/socklnd/socklnd_cb.c @@ -1698,7 +1698,7 @@ ksocknal_send_hello (ksock_conn_t *conn, __u32 *ipaddrs, int nipaddrs) int rc; LASSERT (conn->ksnc_type != SOCKNAL_CONN_NONE); - LASSERT (nipaddrs <= SOCKNAL_MAX_INTERFACES); + LASSERT (nipaddrs <= PTL_MAX_INTERFACES); /* No need for getconnsock/putconnsock */ LASSERT (!conn->ksnc_closing); @@ -1867,7 +1867,7 @@ ksocknal_recv_hello (ksock_conn_t *conn, ptl_nid_t *nid, nips = __le32_to_cpu (hdr.payload_length) / sizeof (__u32); - if (nips > SOCKNAL_MAX_INTERFACES || + if (nips > PTL_MAX_INTERFACES || nips * sizeof(__u32) != __le32_to_cpu (hdr.payload_length)) { CERROR("Bad payload length %d from %s ip %u.%u.%u.%u\n", __le32_to_cpu (hdr.payload_length), diff --git a/lnet/klnds/socklnd/socklnd_lib-linux.c b/lnet/klnds/socklnd/socklnd_lib-linux.c index 14a3427e..ff540bd 100644 --- a/lnet/klnds/socklnd/socklnd_lib-linux.c +++ b/lnet/klnds/socklnd/socklnd_lib-linux.c @@ -948,6 +948,189 @@ ksocknal_lib_connect_sock(struct socket **sockp, int *fatal, return rc; } +int +ksocknal_lib_getifaddr(struct socket *sock, char *name, __u32 *ip, __u32 *mask) +{ + mm_segment_t oldmm = get_fs(); + struct ifreq ifr; + int rc; + __u32 val; + + LASSERT (strnlen(name, IFNAMSIZ) < IFNAMSIZ); + + strcpy(ifr.ifr_name, name); + ifr.ifr_addr.sa_family = AF_INET; + set_fs(KERNEL_DS); + rc = sock->ops->ioctl(sock, SIOCGIFADDR, (unsigned long)&ifr); + set_fs(oldmm); + + if (rc != 0) + return rc; + + val = ((struct sockaddr_in *)&ifr.ifr_addr)->sin_addr.s_addr; + *ip = ntohl(val); + + strcpy(ifr.ifr_name, name); + ifr.ifr_addr.sa_family = AF_INET; + set_fs(KERNEL_DS); + rc = sock->ops->ioctl(sock, SIOCGIFNETMASK, (unsigned long)&ifr); + set_fs(oldmm); + + if (rc != 0) + return rc; + + val = ((struct sockaddr_in *)&ifr.ifr_netmask)->sin_addr.s_addr; + *mask = ntohl(val); + return 0; +} + +int +ksocknal_lib_init_if (ksock_interface_t *iface, char *name) +{ + struct socket *sock; + int rc; + int nob; + + rc = sock_create (PF_INET, SOCK_STREAM, 0, &sock); + if (rc != 0) { + CERROR ("Can't create socket: %d\n", rc); + return rc; + } + + nob = strnlen(name, IFNAMSIZ); + if (nob == IFNAMSIZ) { + CERROR("Interface name %s too long\n", name); + rc -EINVAL; + } else { + CLASSERT (sizeof(iface->ksni_name) >= IFNAMSIZ); + strcpy(iface->ksni_name, name); + + rc = ksocknal_lib_getifaddr(sock, name, + &iface->ksni_ipaddr, + &iface->ksni_netmask); + if (rc != 0) + CERROR("Can't get IP address for interface %s\n", name); + } + + sock_release(sock); + return rc; +} + +int +ksocknal_lib_enumerate_ifs (ksock_interface_t *ifs, int nifs) +{ + int nalloc = PTL_MAX_INTERFACES; + char name[IFNAMSIZ]; + int nfound; + int nused; + struct socket *sock; + struct ifconf ifc; + struct ifreq *ifr; + mm_segment_t oldmm = get_fs(); + __u32 ipaddr; + __u32 netmask; + int rc; + int i; + + rc = sock_create (PF_INET, SOCK_STREAM, 0, &sock); + if (rc != 0) { + CERROR ("Can't create socket: %d\n", rc); + return rc; + } + + for (;;) { + PORTAL_ALLOC(ifr, nalloc * sizeof(*ifr)); + if (ifr == NULL) { + CERROR ("ENOMEM enumerating up to %d interfaces\n", nalloc); + rc = -ENOMEM; + goto out0; + } + + ifc.ifc_buf = (char *)ifr; + ifc.ifc_len = nalloc * sizeof(*ifr); + + set_fs(KERNEL_DS); + rc = sock->ops->ioctl(sock, SIOCGIFCONF, (unsigned long)&ifc); + set_fs(oldmm); + + if (rc < 0) { + CERROR ("Error %d enumerating interfaces\n", rc); + goto out1; + } + + LASSERT (rc == 0); + nfound = rc/sizeof(*ifr); + LASSERT (nfound <= nalloc); + + if (nfound <= nalloc) + break; + + /* Assume there are more interfaces */ + if (nalloc >= 16 * PTL_MAX_INTERFACES) { + CWARN("Too many interfaces: " + "only trying the first %d\n", nfound); + break; + } + + nalloc *= 2; + } + + for (i = nused = 0; i < nfound; i++) { + strncpy(name, ifr[i].ifr_name, IFNAMSIZ); /* ensure terminated name */ + name[IFNAMSIZ-1] = 0; + + if (!strncmp(name, "lo", 2)) { + CDEBUG(D_WARNING, "ignoring %s\n", name); + continue; + } + + strcpy(ifr[i].ifr_name, name); + set_fs(KERNEL_DS); + rc = sock->ops->ioctl(sock, SIOCGIFFLAGS, + (unsigned long)&ifr[i]); + set_fs(oldmm); + + if (rc != 0) { + CDEBUG(D_WARNING, "Can't get flags for %s\n", name); + continue; + } + + if ((ifr[i].ifr_flags & IFF_UP) == 0) { + CDEBUG(D_WARNING, "Interface %s down\n", name); + continue; + } + + rc = ksocknal_lib_getifaddr(sock, name, &ipaddr, &netmask); + if (rc != 0) { + CDEBUG(D_WARNING, + "Can't get IP address or netmask for %s\n", + name); + continue; + } + + if (nused >= nifs) { + CWARN("Too many available interfaces: " + "only using the first %d\n", nused); + break; + } + + memset(&ifs[nused], 0, sizeof(ifs[nused])); + + CLASSERT(sizeof(ifs[nused].ksni_name) >= IFNAMSIZ); + strcpy(ifs[nused].ksni_name, name); + ifs[nused].ksni_ipaddr = ipaddr; + ifs[nused].ksni_netmask = netmask; + nused++; + } + + rc = nused; + out1: + PORTAL_FREE(ifr, nalloc * sizeof(*ifr)); + out0: + sock_release(sock); + return rc; +} + #if (LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0)) struct tcp_opt *sock2tcp_opt(struct sock *sk) { diff --git a/lnet/lnet/api-ni.c b/lnet/lnet/api-ni.c index c28d2f8..38e1352 100644 --- a/lnet/lnet/api-ni.c +++ b/lnet/lnet/api-ni.c @@ -636,6 +636,10 @@ ptl_shutdown_nalnis (void) ptl_apini.apini_nzombie_nis--; } PTL_UNLOCK(flags); + + LASSERT (ptl_apini.apini_network_tokens != NULL); + PORTAL_FREE(ptl_apini.apini_network_tokens, + ptl_apini.apini_network_tokens_nob); } ptl_err_t @@ -652,8 +656,8 @@ ptl_startup_nalnis (void) INIT_LIST_HEAD(&nilist); rc = ptl_parse_networks(&nilist, networks); - if (rc != PTL_OK) - return rc; + if (rc != PTL_OK) + goto failed; while (!list_empty(&nilist)) { ni = list_entry(nilist.next, ptl_ni_t, ni_list); diff --git a/lnet/lnet/config.c b/lnet/lnet/config.c index 6873cce..badecb4 100644 --- a/lnet/lnet/config.c +++ b/lnet/lnet/config.c @@ -201,6 +201,8 @@ ptl_parse_networks(struct list_head *nilist, char *networks) return PTL_FAIL; } + ptl_apini.apini_network_tokens = tokens; + ptl_apini.apini_network_tokens_nob = tokensize; memcpy (tokens, networks, tokensize); str = tokens; @@ -311,7 +313,6 @@ ptl_parse_networks(struct list_head *nilist, char *networks) LCONSOLE_ERROR("No networks specified\n"); goto failed; } - PORTAL_FREE(tokens, tokensize); return PTL_OK; failed: @@ -322,6 +323,8 @@ ptl_parse_networks(struct list_head *nilist, char *networks) PORTAL_FREE(ni, sizeof(*ni)); } PORTAL_FREE(tokens, tokensize); + ptl_apini.apini_network_tokens = NULL; + return PTL_FAIL; }