diff options
-rw-r--r-- | src/include/gnunet_testbed_service.h | 21 | ||||
-rw-r--r-- | src/testbed/gnunet-service-testbed.c | 45 | ||||
-rw-r--r-- | src/testbed/testbed_api.c | 111 | ||||
-rw-r--r-- | src/testbed/testbed_api_hosts.c | 86 | ||||
-rw-r--r-- | src/testbed/testbed_api_hosts.h | 26 |
5 files changed, 171 insertions, 118 deletions
diff --git a/src/include/gnunet_testbed_service.h b/src/include/gnunet_testbed_service.h index 6b50efe97..a3f092172 100644 --- a/src/include/gnunet_testbed_service.h +++ b/src/include/gnunet_testbed_service.h | |||
@@ -88,6 +88,26 @@ GNUNET_TESTBED_host_create (const char *hostname, | |||
88 | uint16_t port); | 88 | uint16_t port); |
89 | 89 | ||
90 | 90 | ||
91 | |||
92 | /** | ||
93 | * Create a host to run peers and controllers on. This function is used | ||
94 | * if a peer learns about a host via IPC between controllers (and thus | ||
95 | * some higher-level controller has already determined the unique IDs). | ||
96 | * | ||
97 | * @param id global host ID assigned to the host; 0 is | ||
98 | * reserved to always mean 'localhost' | ||
99 | * @param hostname name of the host, use "NULL" for localhost | ||
100 | * @param username username to use for the login; may be NULL | ||
101 | * @param port port number to use for ssh; use 0 to let ssh decide | ||
102 | * @return handle to the host, NULL on error | ||
103 | */ | ||
104 | struct GNUNET_TESTBED_Host * | ||
105 | GNUNET_TESTBED_host_create_with_id (uint32_t id, | ||
106 | const char *hostname, | ||
107 | const char *username, | ||
108 | uint16_t port); | ||
109 | |||
110 | |||
91 | /** | 111 | /** |
92 | * Load a set of hosts from a configuration file. | 112 | * Load a set of hosts from a configuration file. |
93 | * | 113 | * |
@@ -785,7 +805,6 @@ GNUNET_TESTBED_overlay_configure_topology (void *op_cls, | |||
785 | ...); | 805 | ...); |
786 | 806 | ||
787 | 807 | ||
788 | |||
789 | /** | 808 | /** |
790 | * Ask the testbed controller to write the current overlay topology to | 809 | * Ask the testbed controller to write the current overlay topology to |
791 | * a file. Naturally, the file will only contain a snapshot as the | 810 | * a file. Naturally, the file will only contain a snapshot as the |
diff --git a/src/testbed/gnunet-service-testbed.c b/src/testbed/gnunet-service-testbed.c index 665af9d3a..327daf584 100644 --- a/src/testbed/gnunet-service-testbed.c +++ b/src/testbed/gnunet-service-testbed.c | |||
@@ -55,6 +55,11 @@ struct Context | |||
55 | 55 | ||
56 | 56 | ||
57 | /** | 57 | /** |
58 | * Wrapped stdin. | ||
59 | */ | ||
60 | static struct GNUNET_DISK_FileHandle *fh; | ||
61 | |||
62 | /** | ||
58 | * The master context; generated with the first INIT message | 63 | * The master context; generated with the first INIT message |
59 | */ | 64 | */ |
60 | static struct Context *master_context; | 65 | static struct Context *master_context; |
@@ -139,8 +144,13 @@ handle_addhost (void *cls, | |||
139 | host = GNUNET_TESTBED_host_create (hostname, username, ntohs | 144 | host = GNUNET_TESTBED_host_create (hostname, username, ntohs |
140 | (msg->ssh_port)); | 145 | (msg->ssh_port)); |
141 | /* Store host in a hashmap? But the host_id will be different */ | 146 | /* Store host in a hashmap? But the host_id will be different */ |
147 | /* hashmap? maybe array? 4-8 bytes/host and O(1) lookup vs. | ||
148 | > 80 bytes for hash map with slightly worse lookup; only | ||
149 | if we really get a tiny fraction of the hosts, the hash | ||
150 | map would result in any savings... (GNUNET_array_grow) */ | ||
142 | } | 151 | } |
143 | 152 | ||
153 | |||
144 | /** | 154 | /** |
145 | * Task to clean up and shutdown nicely | 155 | * Task to clean up and shutdown nicely |
146 | * | 156 | * |
@@ -151,8 +161,16 @@ static void | |||
151 | shutdown_task (void *cls, | 161 | shutdown_task (void *cls, |
152 | const struct GNUNET_SCHEDULER_TaskContext *tc) | 162 | const struct GNUNET_SCHEDULER_TaskContext *tc) |
153 | { | 163 | { |
164 | shutdown_task_id = GNUNET_SCHEDULER_NO_TASK; | ||
165 | GNUNET_SCHEDULER_shutdown (); | ||
154 | LOG (GNUNET_ERROR_TYPE_DEBUG, "Shutting down testbed service\n"); | 166 | LOG (GNUNET_ERROR_TYPE_DEBUG, "Shutting down testbed service\n"); |
167 | if (NULL != fh) | ||
168 | { | ||
169 | GNUNET_DISK_file_close (fh); | ||
170 | fh = NULL; | ||
171 | } | ||
155 | GNUNET_free_non_null (master_context); | 172 | GNUNET_free_non_null (master_context); |
173 | master_context = NULL; | ||
156 | } | 174 | } |
157 | 175 | ||
158 | 176 | ||
@@ -171,9 +189,12 @@ client_disconnect_cb (void *cls, struct GNUNET_SERVER_Client *client) | |||
171 | { | 189 | { |
172 | LOG (GNUNET_ERROR_TYPE_DEBUG, "Master client disconnected\n"); | 190 | LOG (GNUNET_ERROR_TYPE_DEBUG, "Master client disconnected\n"); |
173 | GNUNET_SERVER_client_drop (client); | 191 | GNUNET_SERVER_client_drop (client); |
174 | GNUNET_SCHEDULER_cancel (shutdown_task_id); | 192 | /* should not be needed as we're terminated by failure to read |
175 | shutdown_task_id = | 193 | from stdin, but if stdin fails for some reason, this shouldn't |
176 | GNUNET_SCHEDULER_add_now (&shutdown_task, NULL); | 194 | hurt for now --- might need to revise this later if we ever |
195 | decide that master connections might be temporarily down | ||
196 | for some reason */ | ||
197 | GNUNET_SCHEDULER_shutdown (); | ||
177 | } | 198 | } |
178 | } | 199 | } |
179 | 200 | ||
@@ -202,11 +223,19 @@ testbed_run (void *cls, | |||
202 | message_handlers); | 223 | message_handlers); |
203 | GNUNET_SERVER_disconnect_notify (server, | 224 | GNUNET_SERVER_disconnect_notify (server, |
204 | &client_disconnect_cb, | 225 | &client_disconnect_cb, |
205 | NULL); | 226 | NULL); |
206 | shutdown_task_id = | 227 | fh = GNUNET_DISK_get_handle_from_native (stdin); |
207 | GNUNET_SCHEDULER_add_delayed (GNUNET_TIME_UNIT_FOREVER_REL, | 228 | if (NULL == fh) |
208 | &shutdown_task, | 229 | shutdown_task_id = |
209 | NULL); | 230 | GNUNET_SCHEDULER_add_delayed (GNUNET_TIME_UNIT_FOREVER_REL, |
231 | &shutdown_task, | ||
232 | NULL); | ||
233 | else | ||
234 | shutdown_task_id = | ||
235 | GNUNET_SCHEDULER_add_read_file (GNUNET_TIME_UNIT_FOREVER_REL, | ||
236 | fh, | ||
237 | &shutdown_task, | ||
238 | NULL); | ||
210 | } | 239 | } |
211 | 240 | ||
212 | 241 | ||
diff --git a/src/testbed/testbed_api.c b/src/testbed/testbed_api.c index 5d34640fa..3f49890c4 100644 --- a/src/testbed/testbed_api.c +++ b/src/testbed/testbed_api.c | |||
@@ -123,9 +123,37 @@ struct GNUNET_TESTBED_Controller | |||
123 | * The controller event mask | 123 | * The controller event mask |
124 | */ | 124 | */ |
125 | uint64_t event_mask; | 125 | uint64_t event_mask; |
126 | |||
127 | /** | ||
128 | * Did we start the receive loop yet? | ||
129 | */ | ||
130 | int in_receive; | ||
126 | }; | 131 | }; |
127 | 132 | ||
128 | 133 | ||
134 | |||
135 | /** | ||
136 | * Handler for messages from controller (testbed service) | ||
137 | * | ||
138 | * @param cls the controller handler | ||
139 | * @param msg message received, NULL on timeout or fatal error | ||
140 | */ | ||
141 | static void | ||
142 | message_handler (void *cls, const struct GNUNET_MessageHeader *msg) | ||
143 | { | ||
144 | struct GNUNET_TESTBED_Controller *c = cls; | ||
145 | |||
146 | /* FIXME: Add checks for message integrity */ | ||
147 | switch (ntohs (msg->type)) | ||
148 | { | ||
149 | default: | ||
150 | GNUNET_break (0); | ||
151 | } | ||
152 | GNUNET_CLIENT_receive (c->client, &message_handler, c, | ||
153 | GNUNET_TIME_UNIT_FOREVER_REL); | ||
154 | } | ||
155 | |||
156 | |||
129 | /** | 157 | /** |
130 | * Function called to notify a client about the connection begin ready to queue | 158 | * Function called to notify a client about the connection begin ready to queue |
131 | * more data. "buf" will be NULL and "size" zero if the connection was closed | 159 | * more data. "buf" will be NULL and "size" zero if the connection was closed |
@@ -159,6 +187,13 @@ transmit_ready_notify (void *cls, size_t size, void *buf) | |||
159 | GNUNET_TIME_UNIT_FOREVER_REL, | 187 | GNUNET_TIME_UNIT_FOREVER_REL, |
160 | GNUNET_NO, &transmit_ready_notify, | 188 | GNUNET_NO, &transmit_ready_notify, |
161 | c); | 189 | c); |
190 | if ( (GNUNET_NO == c->in_receive) && | ||
191 | (size > 0) ) | ||
192 | { | ||
193 | c->in_receive = GNUNET_YES; | ||
194 | GNUNET_CLIENT_receive (c->client, &message_handler, c, | ||
195 | GNUNET_TIME_UNIT_FOREVER_REL); | ||
196 | } | ||
162 | return size; | 197 | return size; |
163 | } | 198 | } |
164 | 199 | ||
@@ -198,61 +233,6 @@ queue_message (struct GNUNET_TESTBED_Controller *controller, | |||
198 | 233 | ||
199 | 234 | ||
200 | /** | 235 | /** |
201 | * Handler for messages from controller (testbed service) | ||
202 | * | ||
203 | * @param cls the controller handler | ||
204 | * @param msg message received, NULL on timeout or fatal error | ||
205 | */ | ||
206 | static void | ||
207 | message_handler (void *cls, const struct GNUNET_MessageHeader *msg) | ||
208 | { | ||
209 | struct GNUNET_TESTBED_Controller *c = cls; | ||
210 | |||
211 | /* FIXME: Add checks for message integrity */ | ||
212 | switch (ntohs (msg->type)) | ||
213 | { | ||
214 | default: | ||
215 | GNUNET_break (0); | ||
216 | } | ||
217 | GNUNET_CLIENT_receive (c->client, &message_handler, c, | ||
218 | GNUNET_TIME_UNIT_FOREVER_REL); | ||
219 | } | ||
220 | |||
221 | |||
222 | /** | ||
223 | * ?Callback for messages recevied from server? | ||
224 | * | ||
225 | * Do not call GNUNET_SERVER_mst_destroy in callback | ||
226 | * | ||
227 | * @param cls closure | ||
228 | * @param client identification of the client | ||
229 | * @param message the actual message | ||
230 | * | ||
231 | * @return GNUNET_OK on success, GNUNET_SYSERR to stop further processing | ||
232 | */ | ||
233 | static int | ||
234 | server_mst_cb (void *cls, void *client, | ||
235 | const struct GNUNET_MessageHeader *message) | ||
236 | { | ||
237 | struct GNUNET_TESTBED_Controller *c = cls; | ||
238 | struct GNUNET_TESTBED_InitMessage *msg; | ||
239 | |||
240 | c->client = GNUNET_CLIENT_connect ("testbed", c->cfg); | ||
241 | if (NULL == c->client) | ||
242 | return GNUNET_SYSERR; /* FIXME: Call controller startup_cb ? */ | ||
243 | GNUNET_CLIENT_receive (c->client, &message_handler, c, | ||
244 | GNUNET_TIME_UNIT_FOREVER_REL); | ||
245 | msg = GNUNET_malloc (sizeof (struct GNUNET_TESTBED_InitMessage)); | ||
246 | msg->header.type = htons (GNUNET_MESSAGE_TYPE_TESTBED_INIT); | ||
247 | msg->header.size = htons (sizeof (struct GNUNET_TESTBED_InitMessage)); | ||
248 | msg->host_id = htonl (GNUNET_TESTBED_host_get_id_ (c->host)); | ||
249 | msg->event_mask = GNUNET_htonll (c->event_mask); | ||
250 | queue_message (c, (struct GNUNET_MessageHeader *) msg); | ||
251 | return GNUNET_OK; | ||
252 | } | ||
253 | |||
254 | |||
255 | /** | ||
256 | * Start a controller process using the given configuration at the | 236 | * Start a controller process using the given configuration at the |
257 | * given host. | 237 | * given host. |
258 | * | 238 | * |
@@ -279,9 +259,10 @@ GNUNET_TESTBED_controller_start (const struct GNUNET_CONFIGURATION_Handle *cfg, | |||
279 | "gnunet-service-testbed", | 259 | "gnunet-service-testbed", |
280 | NULL | 260 | NULL |
281 | }; | 261 | }; |
262 | struct GNUNET_TESTBED_InitMessage *msg; | ||
263 | |||
282 | controller = GNUNET_malloc (sizeof (struct GNUNET_TESTBED_Controller)); | 264 | controller = GNUNET_malloc (sizeof (struct GNUNET_TESTBED_Controller)); |
283 | controller->helper = GNUNET_TESTBED_host_run_ (host, binary_argv, | 265 | controller->helper = GNUNET_TESTBED_host_run_ (host, binary_argv); |
284 | &server_mst_cb, controller); | ||
285 | if (NULL == controller->helper) | 266 | if (NULL == controller->helper) |
286 | { | 267 | { |
287 | GNUNET_free (controller); | 268 | GNUNET_free (controller); |
@@ -292,6 +273,18 @@ GNUNET_TESTBED_controller_start (const struct GNUNET_CONFIGURATION_Handle *cfg, | |||
292 | controller->cc_cls = cc_cls; | 273 | controller->cc_cls = cc_cls; |
293 | controller->event_mask = event_mask; | 274 | controller->event_mask = event_mask; |
294 | controller->cfg = GNUNET_CONFIGURATION_dup (cfg); | 275 | controller->cfg = GNUNET_CONFIGURATION_dup (cfg); |
276 | controller->client = GNUNET_CLIENT_connect ("testbed", controller->cfg); | ||
277 | if (NULL == controller->client) | ||
278 | { | ||
279 | GNUNET_TESTBED_controller_stop (controller); | ||
280 | return NULL; | ||
281 | } | ||
282 | msg = GNUNET_malloc (sizeof (struct GNUNET_TESTBED_InitMessage)); | ||
283 | msg->header.type = htons (GNUNET_MESSAGE_TYPE_TESTBED_INIT); | ||
284 | msg->header.size = htons (sizeof (struct GNUNET_TESTBED_InitMessage)); | ||
285 | msg->host_id = htonl (GNUNET_TESTBED_host_get_id_ (controller->host)); | ||
286 | msg->event_mask = GNUNET_htonll (controller->event_mask); | ||
287 | queue_message (controller, (struct GNUNET_MessageHeader *) msg); | ||
295 | return controller; | 288 | return controller; |
296 | } | 289 | } |
297 | 290 | ||
@@ -338,7 +331,8 @@ GNUNET_TESTBED_controller_stop (struct GNUNET_TESTBED_Controller *controller) | |||
338 | GNUNET_free (mq_entry->msg); | 331 | GNUNET_free (mq_entry->msg); |
339 | GNUNET_free (mq_entry); | 332 | GNUNET_free (mq_entry); |
340 | } | 333 | } |
341 | GNUNET_CLIENT_disconnect (controller->client); | 334 | if (NULL != controller->client) |
335 | GNUNET_CLIENT_disconnect (controller->client); | ||
342 | GNUNET_TESTBED_host_stop_ (controller->helper); | 336 | GNUNET_TESTBED_host_stop_ (controller->helper); |
343 | GNUNET_CONFIGURATION_destroy (controller->cfg); | 337 | GNUNET_CONFIGURATION_destroy (controller->cfg); |
344 | GNUNET_free (controller); | 338 | GNUNET_free (controller); |
@@ -391,6 +385,7 @@ void | |||
391 | GNUNET_TESTBED_overlay_write_topology_to_file (struct GNUNET_TESTBED_Controller *controller, | 385 | GNUNET_TESTBED_overlay_write_topology_to_file (struct GNUNET_TESTBED_Controller *controller, |
392 | const char *filename) | 386 | const char *filename) |
393 | { | 387 | { |
388 | GNUNET_break (0); | ||
394 | } | 389 | } |
395 | 390 | ||
396 | 391 | ||
diff --git a/src/testbed/testbed_api_hosts.c b/src/testbed/testbed_api_hosts.c index a12d6ce11..c4dfcf3c9 100644 --- a/src/testbed/testbed_api_hosts.c +++ b/src/testbed/testbed_api_hosts.c | |||
@@ -132,7 +132,7 @@ GNUNET_TESTBED_host_create_by_id_ (uint32_t id) | |||
132 | uint32_t | 132 | uint32_t |
133 | GNUNET_TESTBED_host_get_id_ (const struct GNUNET_TESTBED_Host *host) | 133 | GNUNET_TESTBED_host_get_id_ (const struct GNUNET_TESTBED_Host *host) |
134 | { | 134 | { |
135 | return host->unique_id; | 135 | return host->unique_id; |
136 | } | 136 | } |
137 | 137 | ||
138 | 138 | ||
@@ -147,10 +147,10 @@ GNUNET_TESTBED_host_get_id_ (const struct GNUNET_TESTBED_Host *host) | |||
147 | * @return handle to the host, NULL on error | 147 | * @return handle to the host, NULL on error |
148 | */ | 148 | */ |
149 | struct GNUNET_TESTBED_Host * | 149 | struct GNUNET_TESTBED_Host * |
150 | GNUNET_TESTBED_host_create_with_id_ (uint32_t id, | 150 | GNUNET_TESTBED_host_create_with_id (uint32_t id, |
151 | const char *hostname, | 151 | const char *hostname, |
152 | const char *username, | 152 | const char *username, |
153 | uint16_t port) | 153 | uint16_t port) |
154 | { | 154 | { |
155 | struct GNUNET_TESTBED_Host *host; | 155 | struct GNUNET_TESTBED_Host *host; |
156 | 156 | ||
@@ -180,10 +180,10 @@ GNUNET_TESTBED_host_create (const char *hostname, | |||
180 | static uint32_t uid_generator; | 180 | static uint32_t uid_generator; |
181 | 181 | ||
182 | if (NULL == hostname) | 182 | if (NULL == hostname) |
183 | return GNUNET_TESTBED_host_create_with_id_ (0, hostname, username, port); | 183 | return GNUNET_TESTBED_host_create_with_id (0, hostname, username, port); |
184 | return GNUNET_TESTBED_host_create_with_id_ (++uid_generator, | 184 | return GNUNET_TESTBED_host_create_with_id (++uid_generator, |
185 | hostname, username, | 185 | hostname, username, |
186 | port); | 186 | port); |
187 | } | 187 | } |
188 | 188 | ||
189 | 189 | ||
@@ -198,6 +198,7 @@ unsigned int | |||
198 | GNUNET_TESTBED_hosts_load_from_file (const char *filename, | 198 | GNUNET_TESTBED_hosts_load_from_file (const char *filename, |
199 | struct GNUNET_TESTBED_Host **hosts) | 199 | struct GNUNET_TESTBED_Host **hosts) |
200 | { | 200 | { |
201 | // see testing_group.c, GNUNET_TESTING_hosts_load | ||
201 | GNUNET_break (0); | 202 | GNUNET_break (0); |
202 | return 0; | 203 | return 0; |
203 | } | 204 | } |
@@ -223,9 +224,14 @@ GNUNET_TESTBED_host_destroy (struct GNUNET_TESTBED_Host *host) | |||
223 | struct GNUNET_TESTBED_HelperHandle | 224 | struct GNUNET_TESTBED_HelperHandle |
224 | { | 225 | { |
225 | /** | 226 | /** |
226 | * The helper handle | 227 | * The process handle |
227 | */ | 228 | */ |
228 | struct GNUNET_HELPER_Handle *handle; | 229 | struct GNUNET_OS_Process *process; |
230 | |||
231 | /** | ||
232 | * Pipe connecting to stdin of the process. | ||
233 | */ | ||
234 | struct GNUNET_DISK_PipeHandle *cpipe; | ||
229 | 235 | ||
230 | /** | 236 | /** |
231 | * The port number for ssh; used for helpers starting ssh | 237 | * The port number for ssh; used for helpers starting ssh |
@@ -247,39 +253,62 @@ struct GNUNET_TESTBED_HelperHandle | |||
247 | * | 253 | * |
248 | * @param host host to use, use "NULL" for localhost | 254 | * @param host host to use, use "NULL" for localhost |
249 | * @param binary_argv binary name and command-line arguments to give to the binary | 255 | * @param binary_argv binary name and command-line arguments to give to the binary |
250 | * @param cb function to call for messages received from the binary | ||
251 | * @param cb_cls closure for cb | ||
252 | * @return handle to terminate the command, NULL on error | 256 | * @return handle to terminate the command, NULL on error |
253 | */ | 257 | */ |
254 | struct GNUNET_TESTBED_HelperHandle * | 258 | struct GNUNET_TESTBED_HelperHandle * |
255 | GNUNET_TESTBED_host_run_ (struct GNUNET_TESTBED_Host *host, | 259 | GNUNET_TESTBED_host_run_ (const struct GNUNET_TESTBED_Host *host, |
256 | char *const binary_argv[], | 260 | char *const binary_argv[]) |
257 | GNUNET_SERVER_MessageTokenizerCallback cb, void *cb_cls) | ||
258 | { | 261 | { |
259 | /* FIXME: decide on the SSH command line, prepend it and | ||
260 | run GNUNET_HELPER_start with the modified binary_name and binary_argv! */ | ||
261 | struct GNUNET_TESTBED_HelperHandle *h; | 262 | struct GNUNET_TESTBED_HelperHandle *h; |
262 | char *const local_args[] = {NULL}; | 263 | unsigned int argc; |
263 | 264 | ||
265 | argc = 0; | ||
266 | while (NULL != binary_argv[argc]) | ||
267 | argc++; | ||
264 | h = GNUNET_malloc (sizeof (struct GNUNET_TESTBED_HelperHandle)); | 268 | h = GNUNET_malloc (sizeof (struct GNUNET_TESTBED_HelperHandle)); |
269 | h->cpipe = GNUNET_DISK_pipe (GNUNET_NO, GNUNET_NO, GNUNET_YES, GNUNET_NO); | ||
265 | if (0 == host->unique_id) | 270 | if (0 == host->unique_id) |
266 | { | 271 | { |
267 | h->handle = GNUNET_HELPER_start ("gnunet-service-testbed", local_args, | 272 | h->process = GNUNET_OS_start_process_vap (GNUNET_YES, |
268 | cb, cb_cls); | 273 | h->cpipe, NULL, |
274 | "gnunet-service-testbed", | ||
275 | binary_argv); | ||
269 | } | 276 | } |
270 | else | 277 | else |
271 | { | 278 | { |
279 | char *remote_args[argc + 6 + 1]; | ||
280 | unsigned int argp; | ||
281 | |||
272 | GNUNET_asprintf (&h->port, "%d", host->port); | 282 | GNUNET_asprintf (&h->port, "%d", host->port); |
273 | GNUNET_asprintf (&h->dst, "%s@%s", host->hostname, host->username); | 283 | GNUNET_asprintf (&h->dst, "%s@%s", host->hostname, host->username); |
274 | char *remote_args[] = {"ssh", "-p", h->port, "-q", h->dst, | 284 | argp = 0; |
275 | "gnunet-service-testbed", NULL}; | 285 | remote_args[argp++] = "ssh"; |
276 | h->handle = GNUNET_HELPER_start ("ssh", remote_args, cb, cb_cls); | 286 | remote_args[argp++] = "-p"; |
287 | remote_args[argp++] = h->port; | ||
288 | remote_args[argp++] = "-q"; | ||
289 | remote_args[argp++] = h->dst; | ||
290 | remote_args[argp++] = "gnunet-service-testbed"; | ||
291 | while (NULL != binary_argv[argp-6]) | ||
292 | { | ||
293 | remote_args[argp] = binary_argv[argp - 6]; | ||
294 | argp++; | ||
295 | } | ||
296 | remote_args[argp++] = NULL; | ||
297 | GNUNET_assert (argp == argc + 6 + 1); | ||
298 | h->process = GNUNET_OS_start_process_vap (GNUNET_YES, | ||
299 | h->cpipe, NULL, | ||
300 | "ssh", | ||
301 | remote_args); | ||
277 | } | 302 | } |
278 | if (NULL == h->handle) | 303 | if (NULL == h->process) |
279 | { | 304 | { |
305 | GNUNET_break (GNUNET_OK == GNUNET_DISK_pipe_close (h->cpipe)); | ||
306 | GNUNET_free_non_null (h->port); | ||
307 | GNUNET_free_non_null (h->dst); | ||
280 | GNUNET_free (h); | 308 | GNUNET_free (h); |
281 | return NULL; | 309 | return NULL; |
282 | } | 310 | } |
311 | GNUNET_break (GNUNET_OK == GNUNET_DISK_pipe_close_end (h->cpipe, GNUNET_DISK_PIPE_END_READ)); | ||
283 | return h; | 312 | return h; |
284 | } | 313 | } |
285 | 314 | ||
@@ -292,7 +321,10 @@ GNUNET_TESTBED_host_run_ (struct GNUNET_TESTBED_Host *host, | |||
292 | void | 321 | void |
293 | GNUNET_TESTBED_host_stop_ (struct GNUNET_TESTBED_HelperHandle *handle) | 322 | GNUNET_TESTBED_host_stop_ (struct GNUNET_TESTBED_HelperHandle *handle) |
294 | { | 323 | { |
295 | GNUNET_HELPER_stop (handle->handle); | 324 | GNUNET_break (GNUNET_OK == GNUNET_DISK_pipe_close (handle->cpipe)); |
325 | GNUNET_break (0 == GNUNET_OS_process_kill (handle->process, SIGTERM)); | ||
326 | GNUNET_break (GNUNET_OK == GNUNET_OS_process_wait (handle->process)); | ||
327 | GNUNET_OS_process_destroy (handle->process); | ||
296 | GNUNET_free_non_null (handle->port); | 328 | GNUNET_free_non_null (handle->port); |
297 | GNUNET_free_non_null (handle->dst); | 329 | GNUNET_free_non_null (handle->dst); |
298 | GNUNET_free (handle); | 330 | GNUNET_free (handle); |
diff --git a/src/testbed/testbed_api_hosts.h b/src/testbed/testbed_api_hosts.h index 0c36da0ee..eaf2a4d11 100644 --- a/src/testbed/testbed_api_hosts.h +++ b/src/testbed/testbed_api_hosts.h | |||
@@ -55,25 +55,6 @@ GNUNET_TESTBED_host_create_by_id_ (uint32_t id); | |||
55 | 55 | ||
56 | 56 | ||
57 | /** | 57 | /** |
58 | * Create a host to run peers and controllers on. This function is used | ||
59 | * if a peer learns about a host via IPC between controllers (and thus | ||
60 | * some higher-level controller has already determined the unique IDs). | ||
61 | * | ||
62 | * @param id global host ID assigned to the host; 0 is | ||
63 | * reserved to always mean 'localhost' | ||
64 | * @param hostname name of the host, use "NULL" for localhost | ||
65 | * @param username username to use for the login; may be NULL | ||
66 | * @param port port number to use for ssh; use 0 to let ssh decide | ||
67 | * @return handle to the host, NULL on error | ||
68 | */ | ||
69 | struct GNUNET_TESTBED_Host * | ||
70 | GNUNET_TESTBED_host_create_with_id_ (uint32_t id, | ||
71 | const char *hostname, | ||
72 | const char *username, | ||
73 | uint16_t port); | ||
74 | |||
75 | |||
76 | /** | ||
77 | * Obtain a host's unique global ID. | 58 | * Obtain a host's unique global ID. |
78 | * | 59 | * |
79 | * @param host handle to the host, NULL means 'localhost' | 60 | * @param host handle to the host, NULL means 'localhost' |
@@ -98,14 +79,11 @@ struct GNUNET_TESTBED_HelperHandle; | |||
98 | * | 79 | * |
99 | * @param host host to use, use "NULL" for localhost | 80 | * @param host host to use, use "NULL" for localhost |
100 | * @param binary_argv binary name and command-line arguments to give to the binary | 81 | * @param binary_argv binary name and command-line arguments to give to the binary |
101 | * @param cb function to call for messages received from the binary | ||
102 | * @param cb_cls closure for cb | ||
103 | * @return handle to terminate the command, NULL on error | 82 | * @return handle to terminate the command, NULL on error |
104 | */ | 83 | */ |
105 | struct GNUNET_TESTBED_HelperHandle * | 84 | struct GNUNET_TESTBED_HelperHandle * |
106 | GNUNET_TESTBED_host_run_ (struct GNUNET_TESTBED_Host *host, | 85 | GNUNET_TESTBED_host_run_ (const struct GNUNET_TESTBED_Host *host, |
107 | char *const binary_argv[], | 86 | char *const binary_argv[]); |
108 | GNUNET_SERVER_MessageTokenizerCallback cb, void *cb_cls); | ||
109 | 87 | ||
110 | 88 | ||
111 | /** | 89 | /** |