From 51428f1595436493c13d8c6a583ab6bf72770057 Mon Sep 17 00:00:00 2001 From: Sree Harsha Totakura Date: Tue, 14 May 2013 15:34:49 +0000 Subject: - supermuc specific island handling code --- src/testbed/testbed_api_testbed.c | 197 +++++++++++++++++++++++++++++++++++--- 1 file changed, 186 insertions(+), 11 deletions(-) (limited to 'src') diff --git a/src/testbed/testbed_api_testbed.c b/src/testbed/testbed_api_testbed.c index 5e90b9045..5900a863e 100644 --- a/src/testbed/testbed_api_testbed.c +++ b/src/testbed/testbed_api_testbed.c @@ -87,6 +87,13 @@ enum State */ RC_INIT = 0, +#if ENABLE_LL + /** + * Island level controllers are started and linked + */ + RC_ISLANDS_LINKED, +#endif + /** * Controllers on given hosts started and linked */ @@ -142,6 +149,23 @@ struct CompatibilityCheckContext unsigned int index; }; +#if ENABLE_LL +/** + * Structure to represent an island of SuperMUC's nodes + */ +struct Island +{ + /** + * Array of nodes in this island + */ + struct GNUNET_TESTBED_Host **hosts; + + /** + * Number of nodes in the above array + */ + unsigned int nhosts; +}; +#endif /** * Testbed Run Handle @@ -205,6 +229,13 @@ struct RunContext */ struct GNUNET_TESTBED_Host **hosts; +#if ENABLE_LL + /** + * Array of SuperMUC islands + */ + struct Island **islands; +#endif + /** * Array of compatibility check contexts */ @@ -222,7 +253,8 @@ struct RunContext struct GNUNET_TESTBED_Operation *topology_operation; /** - * The file containing topology data. Only used if the topology is set to 'FROM_FILE' + * The file containing topology data. Only used if the topology is set to + * 'FROM_FILE' */ char *topo_file; @@ -318,6 +350,12 @@ struct RunContext */ unsigned int links_failed; +#if ENABLE_LL + /** + * Number of SuperMUC islands we are running on + */ + unsigned int nislands; +#endif }; @@ -436,6 +474,25 @@ remove_rcop (struct RunContext *rc, struct RunContextOperation *rcop) rcop)); } +#if ENABLE_LL +static void +cleanup_islands (struct RunContext *rc) +{ + struct Island *island; + unsigned int cnt; + + GNUNET_assert (NULL != rc->islands); + for (cnt = 0; cnt < rc->nislands; cnt++) + { + island = rc->islands[cnt]; + GNUNET_free (island->hosts); + GNUNET_free (island); + } + GNUNET_free (rc->islands); + rc->islands = NULL; +} +#endif + /** * Assuming all peers have been destroyed cleanup run handle * @@ -446,7 +503,7 @@ static void cleanup_task (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc) { struct RunContext *rc = cls; - unsigned int hid; + unsigned int cnt; GNUNET_assert (GNUNET_SCHEDULER_NO_TASK == rc->register_hosts_task); GNUNET_assert (NULL == rc->reg_handle); @@ -461,8 +518,12 @@ cleanup_task (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc) GNUNET_TESTBED_controller_stop (rc->cproc); if (NULL != rc->h) GNUNET_TESTBED_host_destroy (rc->h); - for (hid = 0; hid < rc->num_hosts; hid++) - GNUNET_TESTBED_host_destroy (rc->hosts[hid]); +#if ENABLE_LL + if (NULL != rc->islands) + cleanup_islands (rc); +#endif + for (cnt = 0; cnt < rc->num_hosts; cnt++) + GNUNET_TESTBED_host_destroy (rc->hosts[cnt]); GNUNET_free_non_null (rc->hosts); if (NULL != rc->cfg) GNUNET_CONFIGURATION_destroy (rc->cfg); @@ -808,11 +869,41 @@ event_cb (void *cls, const struct GNUNET_TESTBED_EventInformation *event) remove_rcop (rc, rcop); GNUNET_TESTBED_operation_done (rcop->op); GNUNET_free (rcop); - if (rc->reg_hosts == rc->num_hosts) +#if !ENABLE_LL + if (rc->reg_hosts != rc->num_hosts) + return; + rc->state = RC_LINKED; + create_peers (rc); +#else + if (rc->reg_hosts != rc->nislands) + return; + struct Island *island; + struct GNUNET_TESTBED_Host *host; + unsigned int cnt; + unsigned int cnt2; + rc->state = RC_ISLANDS_LINKED; + rc->reg_hosts = 0; + for (cnt = 0; cnt < rc->nislands; cnt++) { - rc->state = RC_LINKED; - create_peers (rc); + island = rc->islands[cnt]; + for (cnt2 = 1; cnt2 < island->nhosts; cnt2++) + { + host = island->hosts[cnt2]; + rcop = GNUNET_malloc (sizeof (struct RunContextOperation)); + rcop->rc = rc; + rcop->op = + GNUNET_TESTBED_controller_link (rcop, rc->c, host, + island->hosts[0], GNUNET_YES); + GNUNET_assert (NULL != rcop->op); + insert_rcop (rc, rcop); + rc->reg_hosts++; + } } + if (0 != rc->reg_hosts) + return; + rc->state = RC_LINKED; + create_peers (rc); +#endif return; default: GNUNET_break (0); @@ -820,6 +911,36 @@ event_cb (void *cls, const struct GNUNET_TESTBED_EventInformation *event) return; } } +#if ENABLE_LL + if (RC_ISLANDS_LINKED == rc->state) + { + switch (event->type) + { + case GNUNET_TESTBED_ET_OPERATION_FINISHED: + rcop = event->op_cls; + if (NULL != event->details.operation_finished.emsg) + { + LOG (GNUNET_ERROR_TYPE_ERROR, + "Linking 2nd level controllers failed. Exiting"); + shutdown_now (rc); + } + else + rc->reg_hosts--; + GNUNET_assert (event->op == rcop->op); + remove_rcop (rc, rcop); + GNUNET_TESTBED_operation_done (rcop->op); + GNUNET_free (rcop); + if (0 != rc->reg_hosts) + return; + rc->state = RC_LINKED; + create_peers (rc); + default: + GNUNET_break (0); + shutdown_now (rc); + return; + } + } +#endif if (GNUNET_TESTBED_ET_OPERATION_FINISHED != event->type) goto call_cc; if (NULL == (rcop = search_rcop (rc, event->op))) @@ -960,23 +1081,39 @@ register_hosts (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc) { struct RunContext *rc = cls; struct RunContextOperation *rcop; - unsigned int slave; + unsigned int cnt; rc->register_hosts_task = GNUNET_SCHEDULER_NO_TASK; if (rc->reg_hosts == rc->num_hosts) { DEBUG ("All hosts successfully registered\n"); - /* Start slaves */ - for (slave = 0; slave < rc->num_hosts; slave++) + /* Start cnts */ +#if !ENABLE_LL + for (cnt = 0; cnt < rc->num_hosts; cnt++) { rcop = GNUNET_malloc (sizeof (struct RunContextOperation)); rcop->rc = rc; rcop->op = - GNUNET_TESTBED_controller_link (rcop, rc->c, rc->hosts[slave], + GNUNET_TESTBED_controller_link (rcop, rc->c, rc->hosts[cnt], rc->h, GNUNET_YES); GNUNET_assert (NULL != rcop->op); insert_rcop (rc, rcop); } +#else + struct Island *island; + for (cnt = 0; cnt < rc->nislands; cnt++) + { + island = rc->islands[cnt]; + GNUNET_assert (0 < island->nhosts); + rcop = GNUNET_malloc (sizeof (struct RunContextOperation)); + rcop->rc = rc; + rcop->op = + GNUNET_TESTBED_controller_link (rcop, rc->c, island->hosts[0], + rc->h, GNUNET_YES); + GNUNET_assert (NULL != rcop->op); + insert_rcop (rc, rcop); + } +#endif rc->reg_hosts = 0; return; } @@ -1173,6 +1310,43 @@ timeout_task (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc) } +#if ENABLE_LL +static void +parse_islands (struct RunContext *rc) +{ +#define ISLANDNAME_SIZE 4 + char island_id[ISLANDNAME_SIZE]; + struct GNUNET_TESTBED_Host *host; + struct Island *island; + const char *hostname; + unsigned int nhost; + + memset (island_id, 0, ISLANDNAME_SIZE); + island = NULL; + for (nhost = 0; nhost < rc->num_hosts; nhost++) + { + host = rc->hosts[nhost]; + hostname = GNUNET_TESTBED_host_get_hostname (host); + GNUNET_assert (NULL != hostname); + if (NULL == island) + { + strncpy (island_id, hostname, ISLANDNAME_SIZE - 1); + island = GNUNET_malloc (sizeof (struct Island)); + } + if (0 == strncmp (island_id, hostname, ISLANDNAME_SIZE - 1)) + { + GNUNET_array_append (island->hosts, island->nhosts, host); + continue; + } + DEBUG ("Adding island `%s' with %u hosts\n", island_id, island->nhosts); + GNUNET_array_append (rc->islands, rc->nislands, island); + island = NULL; + } + if (NULL != island) + GNUNET_array_append (rc->islands, rc->nislands, island); +} +#endif + /** * Convenience method for running a testbed with * a single call. Underlay and overlay topology @@ -1228,6 +1402,7 @@ GNUNET_TESTBED_run (const char *host_filename, _("No hosts loaded from LoadLeveler. Need at least one host\n")); goto error_cleanup; } + parse_islands (rc); #else if (NULL != host_filename) { -- cgit v1.2.3