Whamcloud - gitweb
Land b_smallfix onto HEAD (20040416_1638) (more 2.6 build fixes)
[fs/lustre-release.git] / lnet / ulnds / address.c
1 /* -*- mode: c; c-basic-offset: 8; indent-tabs-mode: nil; -*-
2  * vim:expandtab:shiftwidth=8:tabstop=8:
3  *
4  *  Copyright (c) 2002 Cray Inc.
5  *
6  *   This file is part of Lustre, http://www.lustre.org.
7  *
8  *   Lustre is free software; you can redistribute it and/or
9  *   modify it under the terms of version 2 of the GNU General Public
10  *   License as published by the Free Software Foundation.
11  *
12  *   Lustre is distributed in the hope that it will be useful,
13  *   but WITHOUT ANY WARRANTY; without even the implied warranty of
14  *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15  *   GNU General Public License for more details.
16  *
17  *   You should have received a copy of the GNU General Public License
18  *   along with Lustre; if not, write to the Free Software
19  *   Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
20  */
21
22 /* address.c:
23  * this file provides functions to aquire the IP address of the node
24  * and translate them into a NID/PID pair which supports a static
25  * mapping of virtual nodes into the port range of an IP socket.
26 */
27
28 #include <stdlib.h>
29 #include <netdb.h>
30 #include <unistd.h>
31 #include <stdio.h>
32 #include <portals/p30.h>
33 #include <bridge.h>
34 #include <ipmap.h>
35
36
37 /* Function:  get_node_id
38  * Returns: a 32 bit id for this node, actually a big-endian IP address
39  *
40  * get_node_id() determines the host name and uses the resolver to
41  *  find out its ip address. This is fairly fragile and inflexible, but
42  *  explicitly asking about interfaces and their addresses is very
43  *  complicated and nonportable.
44  */
45 static unsigned int get_node_id(void)
46 {
47     char buffer[255];
48     unsigned int x;
49     struct hostent *he;
50     char * host_envp;
51
52     if (!(host_envp = getenv("PTL_HOSTID")))
53         {
54             gethostname(buffer,sizeof(buffer));
55             he=gethostbyname(buffer);
56             if (he)
57                     x=*(unsigned int *)he->h_addr_list[0];
58             else
59                     x = 0;
60             return(ntohl(x));
61         }
62     else 
63         {
64             if (host_envp[1] != 'x')
65                 {
66                     int a, b, c, d;
67                     sscanf(host_envp, "%d.%d.%d.%d", &a, &b, &c, &d);
68                     return ((a<<24) | (b<<16) | (c<<8) | d);
69                 }
70             else
71                 {
72                     long long hostid = strtoll(host_envp, 0, 0);
73                     return((unsigned int) hostid);
74                 }
75         }
76 }
77
78
79 /* Function:  set_address
80  * Arugments: t: a procnal structure to populate with the request
81  *
82  * set_address performs the bit manipulations to set the nid, pid, and
83  *    iptop8 fields of the procnal structures.
84  *
85  * TODO: fix pidrequest to try to do dynamic binding if PTL_ID_ANY
86  */
87
88 #ifdef DIRECT_IP_MODE
89 void set_address(bridge t,ptl_pid_t pidrequest)
90 {
91     int port;
92     if (pidrequest==(unsigned short)PTL_PID_ANY) port = 0;
93     else port=pidrequest;
94     t->nal_cb->ni.nid=get_node_id();
95     t->nal_cb->ni.pid=port;
96 }
97 #else
98
99 void set_address(bridge t,ptl_pid_t pidrequest)
100 {
101     int virtnode, in_addr, port; 
102     ptl_pid_t pid;
103
104     /* get and remember my node id*/
105     if (!getenv("PTL_VIRTNODE"))
106         virtnode = 0;
107     else 
108         {
109             int maxvnode = PNAL_VNODE_MASK - (PNAL_BASE_PORT 
110                                               >> PNAL_VNODE_SHIFT);
111             virtnode = atoi(getenv("PTL_VIRTNODE"));
112             if (virtnode > maxvnode)
113                 {
114                     fprintf(stderr, "PTL_VIRTNODE of %d is too large - max %d\n",
115                             virtnode, maxvnode);
116                     return;
117                 }
118         }
119     
120     in_addr = get_node_id();
121
122     t->iptop8 = in_addr >> PNAL_HOSTID_SHIFT;/* for making new connections */
123     t->nal_cb->ni.nid = ((in_addr & PNAL_HOSTID_MASK) 
124                             << PNAL_VNODE_SHIFT)
125         + virtnode;
126
127     pid=pidrequest;
128     /* TODO: Support of pid PTL_ID_ANY with virtual nodes needs more work. */
129 #ifdef notyet
130     if (pid==(unsigned short)PTL_PID_ANY) port = 0;
131 #endif
132     if (pid==(unsigned short)PTL_PID_ANY) 
133         {
134             fprintf(stderr, "portal pid PTL_ID_ANY is not currently supported\n");
135             return;
136         }
137     else if (pid > PNAL_PID_MASK)
138         {
139             fprintf(stderr, "portal pid of %d is too large - max %d\n",
140                     pid, PNAL_PID_MASK);
141             return;
142         }
143     else port = ((virtnode << PNAL_VNODE_SHIFT) + pid) + PNAL_BASE_PORT;
144     t->nal_cb->ni.pid=pid;
145 }
146 #endif