diff options
author | Sree Harsha Totakura <totakura@in.tum.de> | 2012-12-02 12:02:38 +0000 |
---|---|---|
committer | Sree Harsha Totakura <totakura@in.tum.de> | 2012-12-02 12:02:38 +0000 |
commit | 020a5d9860368e63c997fb5dd82b2498b85f0584 (patch) | |
tree | d9e6c4aa7635aba4ac59dcf5f96438ea168cc32f /src/testbed | |
parent | 3d6db893ead2345c2d2b6ccce27c25baa4266970 (diff) | |
download | gnunet-020a5d9860368e63c997fb5dd82b2498b85f0584.tar.gz gnunet-020a5d9860368e63c997fb5dd82b2498b85f0584.zip |
hosts file support in GNUNET_TESTBED_run() - fixes 2667
Diffstat (limited to 'src/testbed')
-rw-r--r-- | src/testbed/testbed_api_testbed.c | 398 |
1 files changed, 310 insertions, 88 deletions
diff --git a/src/testbed/testbed_api_testbed.c b/src/testbed/testbed_api_testbed.c index f253cf799..61dc5e741 100644 --- a/src/testbed/testbed_api_testbed.c +++ b/src/testbed/testbed_api_testbed.c | |||
@@ -102,6 +102,11 @@ enum State | |||
102 | RC_INIT = 0, | 102 | RC_INIT = 0, |
103 | 103 | ||
104 | /** | 104 | /** |
105 | * Controllers on given hosts started and linked | ||
106 | */ | ||
107 | RC_LINKED, | ||
108 | |||
109 | /** | ||
105 | * The testbed run is ready and the master callback can be called now. At this | 110 | * The testbed run is ready and the master callback can be called now. At this |
106 | * time the peers are all started and if a topology is provided in the | 111 | * time the peers are all started and if a topology is provided in the |
107 | * configuration the topology would have been attempted | 112 | * configuration the topology would have been attempted |
@@ -131,6 +136,13 @@ struct RunContext | |||
131 | struct GNUNET_TESTBED_Controller *c; | 136 | struct GNUNET_TESTBED_Controller *c; |
132 | 137 | ||
133 | /** | 138 | /** |
139 | * The configuration of the controller. This is based on the cfg given to the | ||
140 | * function GNUNET_TESTBED_run(). We also use this config as a template while | ||
141 | * for peers | ||
142 | */ | ||
143 | struct GNUNET_CONFIGURATION_Handle *cfg; | ||
144 | |||
145 | /** | ||
134 | * Handle to the host on which the controller runs | 146 | * Handle to the host on which the controller runs |
135 | */ | 147 | */ |
136 | struct GNUNET_TESTBED_Host *h; | 148 | struct GNUNET_TESTBED_Host *h; |
@@ -171,6 +183,11 @@ struct RunContext | |||
171 | struct DLLOperation *dll_op_tail; | 183 | struct DLLOperation *dll_op_tail; |
172 | 184 | ||
173 | /** | 185 | /** |
186 | * An array of hosts loaded from the hostkeys file | ||
187 | */ | ||
188 | struct GNUNET_TESTBED_Host **hosts; | ||
189 | |||
190 | /** | ||
174 | * Array of peers which we create | 191 | * Array of peers which we create |
175 | */ | 192 | */ |
176 | struct GNUNET_TESTBED_Peer **peers; | 193 | struct GNUNET_TESTBED_Peer **peers; |
@@ -187,6 +204,21 @@ struct RunContext | |||
187 | char *topo_file; | 204 | char *topo_file; |
188 | 205 | ||
189 | /** | 206 | /** |
207 | * Host registration handle | ||
208 | */ | ||
209 | struct GNUNET_TESTBED_HostRegistrationHandle *reg_handle; | ||
210 | |||
211 | /** | ||
212 | * Host registration task | ||
213 | */ | ||
214 | GNUNET_SCHEDULER_TaskIdentifier register_hosts_task; | ||
215 | |||
216 | /** | ||
217 | * Task to be run while shutting down | ||
218 | */ | ||
219 | GNUNET_SCHEDULER_TaskIdentifier shutdown_run_task; | ||
220 | |||
221 | /** | ||
190 | * The event mask for the controller | 222 | * The event mask for the controller |
191 | */ | 223 | */ |
192 | uint64_t event_mask; | 224 | uint64_t event_mask; |
@@ -202,6 +234,16 @@ struct RunContext | |||
202 | enum GNUNET_TESTBED_TopologyOption topology; | 234 | enum GNUNET_TESTBED_TopologyOption topology; |
203 | 235 | ||
204 | /** | 236 | /** |
237 | * Number of hosts in the given host file | ||
238 | */ | ||
239 | unsigned int num_hosts; | ||
240 | |||
241 | /** | ||
242 | * Number of registered hosts | ||
243 | */ | ||
244 | unsigned int reg_hosts; | ||
245 | |||
246 | /** | ||
205 | * Current peer count for an operation; Set this to 0 and increment for each | 247 | * Current peer count for an operation; Set this to 0 and increment for each |
206 | * successful operation on a peer | 248 | * successful operation on a peer |
207 | */ | 249 | */ |
@@ -305,7 +347,10 @@ cleanup_task (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc) | |||
305 | { | 347 | { |
306 | struct RunContext *rc = cls; | 348 | struct RunContext *rc = cls; |
307 | struct DLLOperation *dll_op; | 349 | struct DLLOperation *dll_op; |
350 | unsigned int hid; | ||
308 | 351 | ||
352 | GNUNET_assert (GNUNET_SCHEDULER_NO_TASK == rc->register_hosts_task); | ||
353 | GNUNET_assert (NULL == rc->reg_handle); | ||
309 | GNUNET_assert (NULL == rc->peers); | 354 | GNUNET_assert (NULL == rc->peers); |
310 | GNUNET_assert (RC_PEERS_DESTROYED == rc->state); | 355 | GNUNET_assert (RC_PEERS_DESTROYED == rc->state); |
311 | if (NULL != rc->c) | 356 | if (NULL != rc->c) |
@@ -314,6 +359,9 @@ cleanup_task (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc) | |||
314 | GNUNET_TESTBED_controller_stop (rc->cproc); | 359 | GNUNET_TESTBED_controller_stop (rc->cproc); |
315 | if (NULL != rc->h) | 360 | if (NULL != rc->h) |
316 | GNUNET_TESTBED_host_destroy (rc->h); | 361 | GNUNET_TESTBED_host_destroy (rc->h); |
362 | for (hid = 0; hid < rc->num_hosts; hid++) | ||
363 | GNUNET_TESTBED_host_destroy (rc->hosts[hid]); | ||
364 | GNUNET_free_non_null (rc->hosts); | ||
317 | if (NULL != rc->dll_op_head) | 365 | if (NULL != rc->dll_op_head) |
318 | { | 366 | { |
319 | LOG (GNUNET_ERROR_TYPE_WARNING, | 367 | LOG (GNUNET_ERROR_TYPE_WARNING, |
@@ -325,12 +373,95 @@ cleanup_task (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc) | |||
325 | GNUNET_free (dll_op); | 373 | GNUNET_free (dll_op); |
326 | } | 374 | } |
327 | } | 375 | } |
376 | if (NULL != rc->cfg) | ||
377 | GNUNET_CONFIGURATION_destroy (rc->cfg); | ||
328 | GNUNET_free_non_null (rc->topo_file); | 378 | GNUNET_free_non_null (rc->topo_file); |
329 | GNUNET_free (rc); | 379 | GNUNET_free (rc); |
330 | } | 380 | } |
331 | 381 | ||
332 | 382 | ||
333 | /** | 383 | /** |
384 | * Stops the testbed run and releases any used resources | ||
385 | * | ||
386 | * @param cls the tesbed run handle | ||
387 | * @param tc the task context from scheduler | ||
388 | */ | ||
389 | static void | ||
390 | shutdown_run (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc) | ||
391 | { | ||
392 | struct RunContext *rc = cls; | ||
393 | struct DLLOperation *dll_op; | ||
394 | unsigned int peer; | ||
395 | |||
396 | GNUNET_assert (GNUNET_SCHEDULER_NO_TASK != rc->shutdown_run_task); | ||
397 | rc->shutdown_run_task = GNUNET_SCHEDULER_NO_TASK; | ||
398 | /* Stop register hosts task if it is running */ | ||
399 | if (GNUNET_SCHEDULER_NO_TASK != rc->register_hosts_task) | ||
400 | { | ||
401 | GNUNET_SCHEDULER_cancel (rc->register_hosts_task); | ||
402 | rc->register_hosts_task = GNUNET_SCHEDULER_NO_TASK; | ||
403 | } | ||
404 | if (NULL != rc->reg_handle) | ||
405 | { | ||
406 | GNUNET_TESTBED_cancel_registration (rc->reg_handle); | ||
407 | rc->reg_handle = NULL; | ||
408 | } | ||
409 | if (NULL != rc->c) | ||
410 | { | ||
411 | if (NULL != rc->peers) | ||
412 | { | ||
413 | if (NULL != rc->topology_operation) | ||
414 | { | ||
415 | GNUNET_TESTBED_operation_done (rc->topology_operation); | ||
416 | rc->topology_operation = NULL; | ||
417 | } | ||
418 | if (RC_INIT == rc->state) | ||
419 | rc->state = RC_READY; /* Even though we haven't called the master callback */ | ||
420 | rc->peer_count = 0; | ||
421 | /* Check if some peers are stopped */ | ||
422 | for (peer = 0; peer < rc->num_peers; peer++) | ||
423 | { | ||
424 | if (PS_STOPPED != rc->peers[peer]->state) | ||
425 | break; | ||
426 | } | ||
427 | if (peer == rc->num_peers) | ||
428 | { | ||
429 | /* All peers are stopped */ | ||
430 | rc->state = RC_PEERS_STOPPED; | ||
431 | for (peer = 0; peer < rc->num_peers; peer++) | ||
432 | { | ||
433 | dll_op = GNUNET_malloc (sizeof (struct DLLOperation)); | ||
434 | dll_op->op = GNUNET_TESTBED_peer_destroy (rc->peers[peer]); | ||
435 | GNUNET_CONTAINER_DLL_insert_tail (rc->dll_op_head, rc->dll_op_tail, | ||
436 | dll_op); | ||
437 | } | ||
438 | return; | ||
439 | } | ||
440 | /* Some peers are stopped */ | ||
441 | for (peer = 0; peer < rc->num_peers; peer++) | ||
442 | { | ||
443 | if (PS_STARTED != rc->peers[peer]->state) | ||
444 | { | ||
445 | rc->peer_count++; | ||
446 | continue; | ||
447 | } | ||
448 | dll_op = GNUNET_malloc (sizeof (struct DLLOperation)); | ||
449 | dll_op->op = GNUNET_TESTBED_peer_stop (rc->peers[peer], NULL, NULL); | ||
450 | dll_op->cls = rc->peers[peer]; | ||
451 | GNUNET_CONTAINER_DLL_insert_tail (rc->dll_op_head, rc->dll_op_tail, | ||
452 | dll_op); | ||
453 | } | ||
454 | if (rc->peer_count != rc->num_peers) | ||
455 | return; | ||
456 | } | ||
457 | } | ||
458 | rc->state = RC_PEERS_DESTROYED; /* No peers are present so we consider the | ||
459 | * state where all peers are destroyed */ | ||
460 | GNUNET_SCHEDULER_add_now (&cleanup_task, rc); | ||
461 | } | ||
462 | |||
463 | |||
464 | /** | ||
334 | * Task to call master task | 465 | * Task to call master task |
335 | * | 466 | * |
336 | * @param cls the run context | 467 | * @param cls the run context |
@@ -353,6 +484,36 @@ call_master (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc) | |||
353 | 484 | ||
354 | 485 | ||
355 | /** | 486 | /** |
487 | * Function to create peers | ||
488 | * | ||
489 | * @param rc the RunContext | ||
490 | */ | ||
491 | static void | ||
492 | create_peers (struct RunContext *rc) | ||
493 | { | ||
494 | struct DLLOperation *dll_op; | ||
495 | unsigned int peer; | ||
496 | |||
497 | rc->peers = | ||
498 | GNUNET_malloc (sizeof (struct GNUNET_TESTBED_Peer *) * rc->num_peers); | ||
499 | GNUNET_assert (NULL != rc->c); | ||
500 | rc->peer_count = 0; | ||
501 | for (peer = 0; peer < rc->num_peers; peer++) | ||
502 | { | ||
503 | dll_op = GNUNET_malloc (sizeof (struct DLLOperation)); | ||
504 | dll_op->rc = rc; | ||
505 | dll_op->op = | ||
506 | GNUNET_TESTBED_peer_create (rc->c, | ||
507 | (0 == rc->num_hosts) | ||
508 | ? rc->h : rc->hosts[peer % rc->num_hosts], | ||
509 | rc->cfg, | ||
510 | peer_create_cb, dll_op); | ||
511 | GNUNET_CONTAINER_DLL_insert_tail (rc->dll_op_head, rc->dll_op_tail, dll_op); | ||
512 | } | ||
513 | } | ||
514 | |||
515 | |||
516 | /** | ||
356 | * Signature of the event handler function called by the | 517 | * Signature of the event handler function called by the |
357 | * respective event controller. | 518 | * respective event controller. |
358 | * | 519 | * |
@@ -366,6 +527,38 @@ event_cb (void *cls, const struct GNUNET_TESTBED_EventInformation *event) | |||
366 | struct DLLOperation *dll_op; | 527 | struct DLLOperation *dll_op; |
367 | unsigned int peer_id; | 528 | unsigned int peer_id; |
368 | 529 | ||
530 | if (RC_INIT == rc->state) | ||
531 | { | ||
532 | switch (event->type) | ||
533 | { | ||
534 | case GNUNET_TESTBED_ET_OPERATION_FINISHED: | ||
535 | dll_op = event->details.operation_finished.op_cls; | ||
536 | if (NULL != event->details.operation_finished.emsg) | ||
537 | { | ||
538 | LOG (GNUNET_ERROR_TYPE_ERROR, | ||
539 | _("Linking controllers failed. Exiting")); | ||
540 | GNUNET_SCHEDULER_cancel (rc->shutdown_run_task); | ||
541 | rc->shutdown_run_task = GNUNET_SCHEDULER_add_now (&shutdown_run, rc); | ||
542 | } | ||
543 | else | ||
544 | rc->reg_hosts++; | ||
545 | GNUNET_assert (event->details.operation_finished.operation == dll_op->op); | ||
546 | GNUNET_CONTAINER_DLL_remove (rc->dll_op_head, rc->dll_op_tail, dll_op); | ||
547 | GNUNET_TESTBED_operation_done (dll_op->op); | ||
548 | GNUNET_free (dll_op); | ||
549 | if (rc->reg_hosts == rc->num_hosts) | ||
550 | { | ||
551 | rc->state = RC_LINKED; | ||
552 | create_peers (rc); | ||
553 | } | ||
554 | return; | ||
555 | default: | ||
556 | GNUNET_assert (0); | ||
557 | GNUNET_SCHEDULER_cancel (rc->shutdown_run_task); | ||
558 | rc->shutdown_run_task = GNUNET_SCHEDULER_add_now (&shutdown_run, rc); | ||
559 | return; | ||
560 | } | ||
561 | } | ||
369 | if (NULL != rc->topology_operation) | 562 | if (NULL != rc->topology_operation) |
370 | { | 563 | { |
371 | switch (event->type) | 564 | switch (event->type) |
@@ -376,6 +569,9 @@ event_cb (void *cls, const struct GNUNET_TESTBED_EventInformation *event) | |||
376 | break; | 569 | break; |
377 | default: | 570 | default: |
378 | GNUNET_assert (0); | 571 | GNUNET_assert (0); |
572 | GNUNET_SCHEDULER_cancel (rc->shutdown_run_task); | ||
573 | rc->shutdown_run_task = GNUNET_SCHEDULER_add_now (&shutdown_run, rc); | ||
574 | return; | ||
379 | } | 575 | } |
380 | if (rc->oc_count == rc->num_oc) | 576 | if (rc->oc_count == rc->num_oc) |
381 | { | 577 | { |
@@ -385,7 +581,7 @@ event_cb (void *cls, const struct GNUNET_TESTBED_EventInformation *event) | |||
385 | } | 581 | } |
386 | return; | 582 | return; |
387 | } | 583 | } |
388 | if ((RC_INIT != rc->state) && | 584 | if ((RC_LINKED < rc->state) && |
389 | ((GNUNET_TESTBED_ET_OPERATION_FINISHED == event->type) || | 585 | ((GNUNET_TESTBED_ET_OPERATION_FINISHED == event->type) || |
390 | (GNUNET_TESTBED_ET_PEER_STOP == event->type))) | 586 | (GNUNET_TESTBED_ET_PEER_STOP == event->type))) |
391 | { | 587 | { |
@@ -496,6 +692,80 @@ call_cc: | |||
496 | } | 692 | } |
497 | 693 | ||
498 | 694 | ||
695 | /** | ||
696 | * Task to register all hosts available in the global host list | ||
697 | * | ||
698 | * @param cls the RunContext | ||
699 | * @param tc the scheduler task context | ||
700 | */ | ||
701 | static void | ||
702 | register_hosts (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc); | ||
703 | |||
704 | |||
705 | /** | ||
706 | * Callback which will be called to after a host registration succeeded or failed | ||
707 | * | ||
708 | * @param cls the closure | ||
709 | * @param emsg the error message; NULL if host registration is successful | ||
710 | */ | ||
711 | static void | ||
712 | host_registration_completion (void *cls, const char *emsg) | ||
713 | { | ||
714 | struct RunContext *rc = cls; | ||
715 | |||
716 | rc->reg_handle = NULL; | ||
717 | if (NULL != emsg) | ||
718 | { | ||
719 | LOG (GNUNET_ERROR_TYPE_WARNING, | ||
720 | _("Host registration failed for a host. Error: %s\n"), emsg); | ||
721 | GNUNET_SCHEDULER_cancel (rc->shutdown_run_task); | ||
722 | rc->shutdown_run_task = GNUNET_SCHEDULER_add_now (&shutdown_run, rc); | ||
723 | return; | ||
724 | } | ||
725 | rc->register_hosts_task = GNUNET_SCHEDULER_add_now (®ister_hosts, rc); | ||
726 | } | ||
727 | |||
728 | |||
729 | /** | ||
730 | * Task to register all hosts available in the global host list | ||
731 | * | ||
732 | * @param cls RunContext | ||
733 | * @param tc the scheduler task context | ||
734 | */ | ||
735 | static void | ||
736 | register_hosts (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc) | ||
737 | { | ||
738 | struct RunContext *rc = cls; | ||
739 | struct DLLOperation *dll_op; | ||
740 | unsigned int slave; | ||
741 | |||
742 | rc->register_hosts_task = GNUNET_SCHEDULER_NO_TASK; | ||
743 | if (rc->reg_hosts == rc->num_hosts) | ||
744 | { | ||
745 | LOG (GNUNET_ERROR_TYPE_DEBUG, | ||
746 | "All hosts successfully registered\n"); | ||
747 | /* Start slaves */ | ||
748 | for (slave = 0; slave < rc->num_hosts; slave++) | ||
749 | { | ||
750 | dll_op = GNUNET_malloc (sizeof (struct DLLOperation)); | ||
751 | dll_op->rc = rc; | ||
752 | dll_op->op = GNUNET_TESTBED_controller_link (dll_op, | ||
753 | rc->c, | ||
754 | rc->hosts[slave], | ||
755 | rc->h, | ||
756 | rc->cfg, | ||
757 | GNUNET_YES); | ||
758 | GNUNET_CONTAINER_DLL_insert_tail (rc->dll_op_head, rc->dll_op_tail, dll_op); | ||
759 | } | ||
760 | rc->reg_hosts = 0; | ||
761 | return; | ||
762 | } | ||
763 | rc->reg_handle = GNUNET_TESTBED_register_host (rc->c, | ||
764 | rc->hosts[rc->reg_hosts++], | ||
765 | host_registration_completion, | ||
766 | rc); | ||
767 | } | ||
768 | |||
499 | 769 | ||
500 | /** | 770 | /** |
501 | * Callback to signal successfull startup of the controller process | 771 | * Callback to signal successfull startup of the controller process |
@@ -511,102 +781,28 @@ controller_status_cb (void *cls, const struct GNUNET_CONFIGURATION_Handle *cfg, | |||
511 | int status) | 781 | int status) |
512 | { | 782 | { |
513 | struct RunContext *rc = cls; | 783 | struct RunContext *rc = cls; |
514 | struct DLLOperation *dll_op; | ||
515 | uint64_t event_mask; | 784 | uint64_t event_mask; |
516 | unsigned int peer; | ||
517 | 785 | ||
518 | if (status != GNUNET_OK) | 786 | if (status != GNUNET_OK) |
519 | { | 787 | { |
520 | GNUNET_log (GNUNET_ERROR_TYPE_WARNING, "Testbed startup failed\n"); | 788 | GNUNET_log (GNUNET_ERROR_TYPE_WARNING, "Testbed startup failed\n"); |
521 | return; | 789 | return; |
522 | } | 790 | } |
791 | rc->cfg = GNUNET_CONFIGURATION_dup (cfg); | ||
523 | event_mask = rc->event_mask; | 792 | event_mask = rc->event_mask; |
524 | event_mask |= (1LL << GNUNET_TESTBED_ET_PEER_STOP); | 793 | event_mask |= (1LL << GNUNET_TESTBED_ET_PEER_STOP); |
525 | event_mask |= (1LL << GNUNET_TESTBED_ET_OPERATION_FINISHED); | 794 | event_mask |= (1LL << GNUNET_TESTBED_ET_OPERATION_FINISHED); |
526 | if (rc->topology < GNUNET_TESTBED_TOPOLOGY_NONE) | 795 | if (rc->topology < GNUNET_TESTBED_TOPOLOGY_NONE) |
527 | event_mask |= GNUNET_TESTBED_ET_CONNECT; | 796 | event_mask |= GNUNET_TESTBED_ET_CONNECT; |
528 | rc->c = | 797 | rc->c = |
529 | GNUNET_TESTBED_controller_connect (cfg, rc->h, event_mask, &event_cb, rc); | 798 | GNUNET_TESTBED_controller_connect (rc->cfg, rc->h, event_mask, &event_cb, rc); |
530 | rc->peers = | 799 | if (0 < rc->num_hosts) |
531 | GNUNET_malloc (sizeof (struct GNUNET_TESTBED_Peer *) * rc->num_peers); | ||
532 | GNUNET_assert (NULL != rc->c); | ||
533 | rc->peer_count = 0; | ||
534 | for (peer = 0; peer < rc->num_peers; peer++) | ||
535 | { | 800 | { |
536 | dll_op = GNUNET_malloc (sizeof (struct DLLOperation)); | 801 | rc->register_hosts_task = GNUNET_SCHEDULER_add_now (®ister_hosts, rc); |
537 | dll_op->rc = rc; | 802 | return; |
538 | dll_op->op = | ||
539 | GNUNET_TESTBED_peer_create (rc->c, rc->h, cfg, peer_create_cb, dll_op); | ||
540 | GNUNET_CONTAINER_DLL_insert_tail (rc->dll_op_head, rc->dll_op_tail, dll_op); | ||
541 | } | ||
542 | } | ||
543 | |||
544 | |||
545 | /** | ||
546 | * Stops the testbed run and releases any used resources | ||
547 | * | ||
548 | * @param cls the tesbed run handle | ||
549 | * @param tc the task context from scheduler | ||
550 | */ | ||
551 | static void | ||
552 | shutdown_run_task (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc) | ||
553 | { | ||
554 | struct RunContext *rc = cls; | ||
555 | struct DLLOperation *dll_op; | ||
556 | unsigned int peer; | ||
557 | |||
558 | if (NULL != rc->c) | ||
559 | { | ||
560 | if (NULL != rc->peers) | ||
561 | { | ||
562 | if (NULL != rc->topology_operation) | ||
563 | { | ||
564 | GNUNET_TESTBED_operation_done (rc->topology_operation); | ||
565 | rc->topology_operation = NULL; | ||
566 | } | ||
567 | if (RC_INIT == rc->state) | ||
568 | rc->state = RC_READY; /* Even though we haven't called the master callback */ | ||
569 | rc->peer_count = 0; | ||
570 | /* Check if some peers are stopped */ | ||
571 | for (peer = 0; peer < rc->num_peers; peer++) | ||
572 | { | ||
573 | if (PS_STOPPED != rc->peers[peer]->state) | ||
574 | break; | ||
575 | } | ||
576 | if (peer == rc->num_peers) | ||
577 | { | ||
578 | /* All peers are stopped */ | ||
579 | rc->state = RC_PEERS_STOPPED; | ||
580 | for (peer = 0; peer < rc->num_peers; peer++) | ||
581 | { | ||
582 | dll_op = GNUNET_malloc (sizeof (struct DLLOperation)); | ||
583 | dll_op->op = GNUNET_TESTBED_peer_destroy (rc->peers[peer]); | ||
584 | GNUNET_CONTAINER_DLL_insert_tail (rc->dll_op_head, rc->dll_op_tail, | ||
585 | dll_op); | ||
586 | } | ||
587 | return; | ||
588 | } | ||
589 | /* Some peers are stopped */ | ||
590 | for (peer = 0; peer < rc->num_peers; peer++) | ||
591 | { | ||
592 | if (PS_STARTED != rc->peers[peer]->state) | ||
593 | { | ||
594 | rc->peer_count++; | ||
595 | continue; | ||
596 | } | ||
597 | dll_op = GNUNET_malloc (sizeof (struct DLLOperation)); | ||
598 | dll_op->op = GNUNET_TESTBED_peer_stop (rc->peers[peer], NULL, NULL); | ||
599 | dll_op->cls = rc->peers[peer]; | ||
600 | GNUNET_CONTAINER_DLL_insert_tail (rc->dll_op_head, rc->dll_op_tail, | ||
601 | dll_op); | ||
602 | } | ||
603 | if (rc->peer_count != rc->num_peers) | ||
604 | return; | ||
605 | } | ||
606 | } | 803 | } |
607 | rc->state = RC_PEERS_DESTROYED; /* No peers are present so we consider the | 804 | rc->state = RC_LINKED; |
608 | * state where all peers are destroyed */ | 805 | create_peers (rc); |
609 | GNUNET_SCHEDULER_add_now (&cleanup_task, rc); | ||
610 | } | 806 | } |
611 | 807 | ||
612 | 808 | ||
@@ -647,15 +843,32 @@ GNUNET_TESTBED_run (const char *host_filename, | |||
647 | struct RunContext *rc; | 843 | struct RunContext *rc; |
648 | char *topology; | 844 | char *topology; |
649 | unsigned long long random_links; | 845 | unsigned long long random_links; |
650 | 846 | unsigned int hid; | |
651 | GNUNET_break (NULL == host_filename); /* Currently we do not support host | 847 | |
652 | * files */ | ||
653 | GNUNET_assert (NULL != cc); | 848 | GNUNET_assert (NULL != cc); |
654 | GNUNET_assert (num_peers > 0); | 849 | GNUNET_assert (num_peers > 0); |
655 | host_filename = NULL; | 850 | host_filename = NULL; |
656 | rc = GNUNET_malloc (sizeof (struct RunContext)); | 851 | rc = GNUNET_malloc (sizeof (struct RunContext)); |
657 | rc->h = GNUNET_TESTBED_host_create (NULL, NULL, 0); | 852 | if (NULL != host_filename) |
853 | { | ||
854 | rc->num_hosts = | ||
855 | GNUNET_TESTBED_hosts_load_from_file (host_filename, &rc->hosts); | ||
856 | if (0 == rc->num_hosts) | ||
857 | { | ||
858 | LOG (GNUNET_ERROR_TYPE_WARNING, | ||
859 | _("No hosts loaded. Need at least one host\n")); | ||
860 | return; | ||
861 | } | ||
862 | rc->h = rc->hosts[0]; | ||
863 | rc->num_hosts--; | ||
864 | if (0 < rc->num_hosts) | ||
865 | rc->hosts = &rc->hosts[1]; | ||
866 | } | ||
867 | else | ||
868 | rc->h = GNUNET_TESTBED_host_create (NULL, NULL, 0); | ||
658 | GNUNET_assert (NULL != rc->h); | 869 | GNUNET_assert (NULL != rc->h); |
870 | /* FIXME: If we are starting controller on different host 127.0.0.1 may not ab | ||
871 | correct */ | ||
659 | rc->cproc = | 872 | rc->cproc = |
660 | GNUNET_TESTBED_controller_start ("127.0.0.1", rc->h, cfg, | 873 | GNUNET_TESTBED_controller_start ("127.0.0.1", rc->h, cfg, |
661 | &controller_status_cb, rc); | 874 | &controller_status_cb, rc); |
@@ -698,6 +911,10 @@ GNUNET_TESTBED_run (const char *host_filename, | |||
698 | if (random_links > UINT32_MAX) | 911 | if (random_links > UINT32_MAX) |
699 | { | 912 | { |
700 | GNUNET_break (0); /* Too big number */ | 913 | GNUNET_break (0); /* Too big number */ |
914 | GNUNET_TESTBED_host_destroy (rc->h); | ||
915 | for (hid = 0; hid < rc->num_hosts; hid++) | ||
916 | GNUNET_TESTBED_host_destroy (rc->hosts[hid]); | ||
917 | GNUNET_free_non_null (rc->hosts); | ||
701 | GNUNET_free (rc); | 918 | GNUNET_free (rc); |
702 | return; | 919 | return; |
703 | } | 920 | } |
@@ -711,12 +928,17 @@ GNUNET_TESTBED_run (const char *host_filename, | |||
711 | { | 928 | { |
712 | /* You need to set TOPOLOGY_FILE option to a topolog file */ | 929 | /* You need to set TOPOLOGY_FILE option to a topolog file */ |
713 | GNUNET_break (0); | 930 | GNUNET_break (0); |
931 | GNUNET_TESTBED_host_destroy (rc->h); | ||
932 | for (hid = 0; hid < rc->num_hosts; hid++) | ||
933 | GNUNET_TESTBED_host_destroy (rc->hosts[hid]); | ||
934 | GNUNET_free_non_null (rc->hosts); | ||
714 | GNUNET_free (rc); | 935 | GNUNET_free (rc); |
715 | return; | 936 | return; |
716 | } | 937 | } |
717 | } | 938 | } |
718 | GNUNET_SCHEDULER_add_delayed (GNUNET_TIME_UNIT_FOREVER_REL, | 939 | rc->shutdown_run_task = |
719 | &shutdown_run_task, rc); | 940 | GNUNET_SCHEDULER_add_delayed (GNUNET_TIME_UNIT_FOREVER_REL, |
941 | &shutdown_run, rc); | ||
720 | } | 942 | } |
721 | 943 | ||
722 | 944 | ||