summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorSree Harsha Totakura <totakura@in.tum.de>2013-05-14 15:34:49 +0000
committerSree Harsha Totakura <totakura@in.tum.de>2013-05-14 15:34:49 +0000
commit51428f1595436493c13d8c6a583ab6bf72770057 (patch)
tree17a814cf8957839b52b46677cbe1a2a2bc9336e2 /src
parent90cf3dbae0ad35e49ae0de58921b90b71d031f6f (diff)
- supermuc specific island handling code
Diffstat (limited to 'src')
-rw-r--r--src/testbed/testbed_api_testbed.c197
1 files changed, 186 insertions, 11 deletions
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)
{