aboutsummaryrefslogtreecommitdiff
path: root/src/testbed/gnunet_testbed_mpi_spawn.c
diff options
context:
space:
mode:
authorSree Harsha Totakura <totakura@in.tum.de>2013-02-27 14:22:24 +0000
committerSree Harsha Totakura <totakura@in.tum.de>2013-02-27 14:22:24 +0000
commitd6353593a73706c2bdbaac7fbb111fca6bdab9a5 (patch)
treeb0d90b7b24fb82c4583d048b3fae0c6f3d35f505 /src/testbed/gnunet_testbed_mpi_spawn.c
parente9a65d965436f0233a30951e89b01503cf88be35 (diff)
downloadgnunet-d6353593a73706c2bdbaac7fbb111fca6bdab9a5.tar.gz
gnunet-d6353593a73706c2bdbaac7fbb111fca6bdab9a5.zip
Parsing LoadLeveler allocated hosts and creating testbed hosts from them
Diffstat (limited to 'src/testbed/gnunet_testbed_mpi_spawn.c')
-rw-r--r--src/testbed/gnunet_testbed_mpi_spawn.c218
1 files changed, 11 insertions, 207 deletions
diff --git a/src/testbed/gnunet_testbed_mpi_spawn.c b/src/testbed/gnunet_testbed_mpi_spawn.c
index c147d460b..2ff1972a6 100644
--- a/src/testbed/gnunet_testbed_mpi_spawn.c
+++ b/src/testbed/gnunet_testbed_mpi_spawn.c
@@ -1,6 +1,7 @@
1#include "platform.h" 1#include "platform.h"
2#include "gnunet_util_lib.h" 2#include "gnunet_util_lib.h"
3#include "gnunet_resolver_service.h" 3#include "gnunet_resolver_service.h"
4#include "gnunet_testbed_service.h"
4#include <mpi.h> 5#include <mpi.h>
5 6
6/** 7/**
@@ -22,216 +23,21 @@
22 GNUNET_TIME_relative_multiply (GNUNET_TIME_UNIT_SECONDS, 30) 23 GNUNET_TIME_relative_multiply (GNUNET_TIME_UNIT_SECONDS, 30)
23 24
24/** 25/**
25 * Log an error message at log-level 'level' that indicates
26 * a failure of the command 'cmd' with the message given
27 * by gcry_strerror(rc).
28 */
29#define LOG_GAI(level, cmd, rc) do { LOG(level, _("`%s' failed at %s:%d with error: %s\n"), cmd, __FILE__, __LINE__, gai_strerror(rc)); } while(0)
30
31/**
32 * Global result 26 * Global result
33 */ 27 */
34static int ret; 28static int ret;
35 29
36/** 30/**
37 * The array of hostnames 31 * The host list
38 */
39static char **hostnames;
40
41/**
42 * The array of host's addresses
43 */
44static char **hostaddrs;
45
46/**
47 * The resolution request handles; one per each hostname resolution
48 */ 32 */
49struct GNUNET_RESOLVER_RequestHandle **rhs; 33static struct GNUNET_TESTBED_Host **hosts;
50 34
51/** 35/**
52 * Number of hosts in the hostname array 36 * Number of hosts in the host list
53 */ 37 */
54static unsigned int nhosts; 38static unsigned int nhosts;
55 39
56/** 40/**
57 * Number of addresses in the hostaddr array
58 */
59static unsigned int nhostaddrs;
60
61/**
62 * Did we connect to the resolver service
63 */
64static unsigned int resolver_connected;
65
66/**
67 * Task for resolving ips
68 */
69static GNUNET_SCHEDULER_TaskIdentifier resolve_task_id;
70
71
72/**
73 * Resolves the hostnames array
74 *
75 * @param cls NULL
76 * @param tc the scheduler task context
77 */
78static void
79resolve_task (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc)
80{
81 struct addrinfo hint;
82 const struct sockaddr_in *in_addr;
83 struct addrinfo *res;
84 char *hostip;
85 unsigned int host;
86 unsigned int rc;
87
88 resolve_task_id = GNUNET_SCHEDULER_NO_TASK;
89 hint.ai_family = AF_INET; /* IPv4 */
90 hint.ai_socktype = 0;
91 hint.ai_protocol = 0;
92 hint.ai_addrlen = 0;
93 hint.ai_addr = NULL;
94 hint.ai_canonname = NULL;
95 hint.ai_next = NULL;
96 hint.ai_flags = AI_NUMERICSERV;
97 for (host = 0; host < nhosts; host++)
98 {
99 res = NULL;
100 LOG_DEBUG ("Resolving: %s host\n", hostnames[host]);
101 if (0 != (rc = getaddrinfo (hostnames[host], "22", &hint, &res)))
102 {
103 LOG_GAI (GNUNET_ERROR_TYPE_ERROR, "getaddrinfo", rc);
104 ret = GNUNET_SYSERR;
105 return;
106 }
107 GNUNET_assert (NULL != res);
108 GNUNET_assert (NULL != res->ai_addr);
109 GNUNET_assert (sizeof (struct sockaddr_in) == res->ai_addrlen);
110 in_addr = (const struct sockaddr_in *) res->ai_addr;
111 hostip = inet_ntoa (in_addr->sin_addr);
112 GNUNET_assert (NULL != hostip);
113 GNUNET_array_append (hostaddrs, nhostaddrs, GNUNET_strdup (hostip));
114 LOG_DEBUG ("%s --> %s\n", hostnames[host], hostaddrs[host]);
115 freeaddrinfo (res);
116 }
117 ret = GNUNET_OK;
118}
119
120
121/**
122 * Loads the set of host allocated by the LoadLeveler Job Scheduler. This
123 * function is only available when compiled with support for LoadLeveler and is
124 * used for running on the SuperMUC
125 *
126 * @param hostlist set to the hosts found in the file; caller must free this if
127 * number of hosts returned is greater than 0
128 * @return number of hosts returned in 'hosts', 0 on error
129 */
130unsigned int
131get_loadleveler_hosts ()
132{
133 const char *hostfile;
134 char *buf;
135 char *hostname;
136 struct addrinfo *ret;
137 struct addrinfo hint;
138 ssize_t rsize;
139 uint64_t size;
140 uint64_t offset;
141 enum {
142 SCAN,
143 SKIP,
144 TRIM,
145 READHOST
146 } pstep;
147 unsigned int host;
148
149 if (NULL == (hostfile = getenv ("MP_SAVEHOSTFILE")))
150 {
151 GNUNET_break (0);
152 return 0;
153 }
154 if (GNUNET_SYSERR == GNUNET_DISK_file_size (hostfile, &size, GNUNET_YES,
155 GNUNET_YES))
156 {
157 GNUNET_break (0);
158 return 0;
159 }
160 if (0 == size)
161 {
162 GNUNET_break (0);
163 return 0;
164 }
165 buf = GNUNET_malloc (size + 1);
166 rsize = GNUNET_DISK_fn_read (hostfile, buf, (size_t) size);
167 if ( (GNUNET_SYSERR == rsize) || ((ssize_t) size != rsize) )
168 {
169 GNUNET_free (buf);
170 GNUNET_break (0);
171 return 0;
172 }
173 size++;
174 offset = 0;
175 pstep = SCAN;
176 hostname = NULL;
177 while (offset < size)
178 {
179 switch (pstep)
180 {
181 case SCAN:
182 if ('!' == buf[offset])
183 pstep = SKIP;
184 else
185 pstep = TRIM;
186 break;
187 case SKIP:
188 if ('\n' == buf[offset])
189 pstep = SCAN;
190 break;
191 case TRIM:
192 if ('!' == buf[offset])
193 {
194 pstep = SKIP;
195 break;
196 }
197 if ( (' ' == buf[offset])
198 || ('\t' == buf[offset])
199 || ('\r' == buf[offset]) )
200 pstep = TRIM;
201 else
202 {
203 pstep = READHOST;
204 hostname = &buf[offset];
205 }
206 break;
207 case READHOST:
208 if (isspace (buf[offset]))
209 {
210 buf[offset] = '\0';
211 for (host = 0; host < nhosts; host++)
212 if (0 == strcmp (hostnames[host], hostname))
213 break;
214 if (host == nhosts)
215 {
216 LOG_DEBUG ("Adding host: %s\n", hostname);
217 hostname = GNUNET_strdup (hostname);
218 GNUNET_array_append (hostnames, nhosts, hostname);
219 }
220 else
221 LOG_DEBUG ("Not adding host %s as it is already included\n", hostname);
222 hostname = NULL;
223 pstep = SCAN;
224 }
225 break;
226 }
227 offset++;
228 }
229 GNUNET_free_non_null (buf);
230 return nhosts;
231}
232
233
234/**
235 * Main function that will be run by the scheduler. 41 * Main function that will be run by the scheduler.
236 * 42 *
237 * @param cls closure 43 * @param cls closure
@@ -247,7 +53,7 @@ run (void *cls, char *const *args, const char *cfgfile,
247 unsigned long code; 53 unsigned long code;
248 enum GNUNET_OS_ProcessStatusType proc_status; 54 enum GNUNET_OS_ProcessStatusType proc_status;
249 int rank; 55 int rank;
250 int msg_size; 56 unsigned int host;
251 57
252 if (MPI_SUCCESS != MPI_Comm_rank (MPI_COMM_WORLD, &rank)) 58 if (MPI_SUCCESS != MPI_Comm_rank (MPI_COMM_WORLD, &rank))
253 { 59 {
@@ -291,13 +97,17 @@ run (void *cls, char *const *args, const char *cfgfile,
291 GNUNET_break (0); 97 GNUNET_break (0);
292 return; 98 return;
293 } 99 }
294 if (0 == get_loadleveler_hosts()) 100 if (0 == (nhosts = GNUNET_TESTBED_hosts_load_from_loadleveler (config, &hosts)))
295 { 101 {
296 GNUNET_break (0); 102 GNUNET_break (0);
297 ret = GNUNET_SYSERR; 103 ret = GNUNET_SYSERR;
298 return; 104 return;
299 } 105 }
300 resolve_task_id = GNUNET_SCHEDULER_add_now (&resolve_task, NULL); 106 for (host = 0; host < nhosts; host++)
107 GNUNET_TESTBED_host_destroy (hosts[host]);
108 GNUNET_free (hosts);
109 hosts = NULL;
110 ret = GNUNET_OK;
301} 111}
302 112
303 113
@@ -330,12 +140,6 @@ main (int argc, char *argv[])
330 _("Spawns cmd after starting my the MPI run-time"), 140 _("Spawns cmd after starting my the MPI run-time"),
331 options, &run, NULL); 141 options, &run, NULL);
332 (void) MPI_Finalize (); 142 (void) MPI_Finalize ();
333 for (host = 0; host < nhosts; host++)
334 GNUNET_free (hostnames[host]);
335 for (host = 0; host < nhostaddrs; host++)
336 GNUNET_free (hostaddrs[host]);
337 GNUNET_free_non_null (hostnames);
338 GNUNET_free_non_null (hostaddrs);
339 if ((GNUNET_OK == rres) && (GNUNET_OK == ret)) 143 if ((GNUNET_OK == rres) && (GNUNET_OK == ret))
340 return 0; 144 return 0;
341 printf ("Something went wrong\n"); 145 printf ("Something went wrong\n");