*/
#define DEFAULT_SETUP_TIMEOUT 300
+/**
+ * Testbed Run Handle
+ */
+struct RunContext;
+
/**
* Context information for the operation we start
*/
*/
RC_INIT = 0,
+#if ENABLE_LL
+ /**
+ * Island level controllers are started and linked
+ */
+ RC_ISLANDS_LINKED,
+#endif
+
/**
* Controllers on given hosts started and linked
*/
};
+/**
+ * Context for host compability checks
+ */
+struct CompatibilityCheckContext
+{
+ /**
+ * The run context
+ */
+ struct RunContext *rc;
+
+ /**
+ * Handle for the compability check
+ */
+ struct GNUNET_TESTBED_HostHabitableCheckHandle *h;
+
+ /**
+ * Index of the host in the run context's hosts array
+ */
+ 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
*/
*/
struct GNUNET_TESTBED_Host **hosts;
+#if ENABLE_LL
+ /**
+ * Array of SuperMUC islands
+ */
+ struct Island **islands;
+#endif
+
/**
- * The handle for whether a host is habitable or not
+ * Array of compatibility check contexts
*/
- struct GNUNET_TESTBED_HostHabitableCheckHandle **hc_handles;
+ struct CompatibilityCheckContext *hclist;
/**
* Array of peers which we create
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;
*/
unsigned int links_failed;
+#if ENABLE_LL
+ /**
+ * Number of SuperMUC islands we are running on
+ */
+ unsigned int nislands;
+#endif
};
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
*
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);
GNUNET_assert (NULL == rc->peers);
- GNUNET_assert (NULL == rc->hc_handles);
+ GNUNET_assert (NULL == rc->hclist);
GNUNET_assert (RC_PEERS_SHUTDOWN == rc->state);
GNUNET_assert (0 == GNUNET_CONTAINER_multihashmap32_size (rc->rcop_map));
GNUNET_CONTAINER_multihashmap32_destroy (rc->rcop_map);
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);
static void
cleanup (struct RunContext *rc)
{
+ struct CompatibilityCheckContext *hc;
unsigned int nhost;
- if (NULL != rc->hc_handles)
+ if (NULL != rc->hclist)
{
for (nhost = 0; nhost < rc->num_hosts; nhost++)
- if (NULL != rc->hc_handles[nhost])
- GNUNET_TESTBED_is_host_habitable_cancel (rc->hc_handles[nhost]);
- GNUNET_free (rc->hc_handles);
- rc->hc_handles = NULL;
+ {
+ hc = &rc->hclist[nhost];
+ if (NULL != hc->h)
+ GNUNET_TESTBED_is_host_habitable_cancel (hc->h);
+ }
+ GNUNET_free (rc->hclist);
+ rc->hclist = NULL;
}
/* Stop register hosts task if it is running */
if (GNUNET_SCHEDULER_NO_TASK != rc->register_hosts_task)
create_peers (struct RunContext *rc)
{
struct RunContextOperation *rcop;
+ struct GNUNET_TESTBED_Host *host;
unsigned int peer;
+#if ENABLE_LL
+ struct Island *island;
+ unsigned int icnt;
+ unsigned int hcnt;
+ island = NULL;
+ icnt = 0;
+ hcnt = 0;
+#endif
DEBUG ("Creating peers\n");
rc->pstart_time = GNUNET_TIME_absolute_get ();
rc->peers =
{
rcop = GNUNET_malloc (sizeof (struct RunContextOperation));
rcop->rc = rc;
- rcop->op =
- GNUNET_TESTBED_peer_create (rc->c,
- (0 ==
- rc->num_hosts) ? rc->h : rc->hosts[peer %
- rc->num_hosts],
- rc->cfg, &peer_create_cb, rcop);
+#if ENABLE_LL
+ if (0 != rc->nislands)
+ {
+ island = rc->islands[icnt];
+ if (hcnt == island->nhosts)
+ {
+ icnt++;
+ if (icnt == rc->nislands)
+ icnt = 0;
+ island = rc->islands[icnt];
+ hcnt = 0;
+ }
+ GNUNET_assert (icnt < rc->nislands);
+ GNUNET_assert (hcnt < island->nhosts);
+ GNUNET_assert (NULL != island->hosts[hcnt]);
+ host = island->hosts[hcnt];
+ hcnt++;
+ }
+ else
+ host = rc->h;
+#else
+ host = (0 == rc->num_hosts) ? rc->h : rc->hosts[peer % rc->num_hosts];
+#endif
+ rcop->op = GNUNET_TESTBED_peer_create (rc->c, host, rc->cfg,
+ &peer_create_cb, rcop);
GNUNET_assert (NULL != rcop->op);
insert_rcop (rc, rcop);
}
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);
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);
+ return;
+ 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)))
{
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],
- rc->h, rc->cfg, GNUNET_YES);
+ 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;
}
}
+#if ENABLE_LL
+#define ISLANDNAME_SIZE 4
+static void
+parse_islands (struct RunContext *rc)
+{
+ char island_id[ISLANDNAME_SIZE];
+ struct GNUNET_TESTBED_Host *host;
+ struct Island *island;
+ const char *hostname;
+ unsigned int nhost;
+
+ DEBUG ("Parsing for islands\n");
+ 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)
+ {
+ DEBUG ("Adding island `%s' with %u hosts\n", island_id, island->nhosts);
+ GNUNET_array_append (rc->islands, rc->nislands, island);
+ }
+ DEBUG ("Total islands parsed: %u\n", rc->nislands);
+}
+#endif
+
+
/**
* Callback function invoked for each interface found.
*
host_habitable_cb (void *cls, const struct GNUNET_TESTBED_Host *host,
int status)
{
- struct RunContext *rc = cls;
+ struct CompatibilityCheckContext *hc = cls;
+ struct RunContext *rc;
struct GNUNET_TESTBED_Host **old_hosts;
unsigned int nhost;
- for (nhost = 0; nhost < rc->num_hosts; nhost++)
- {
- if (host == rc->hosts[nhost])
- break;
- }
- GNUNET_assert (nhost != rc->num_hosts);
- rc->hc_handles[nhost] = NULL;
+ GNUNET_assert (NULL != (rc = hc->rc));
+ nhost = hc->index;
+ GNUNET_assert (nhost <= rc->num_hosts);
+ GNUNET_assert (host == rc->hosts[nhost]);
+ hc->h = NULL;
if (GNUNET_NO == status)
{
if ((NULL != host) && (NULL != GNUNET_TESTBED_host_get_hostname (host)))
rc->reg_hosts++;
if (rc->reg_hosts < rc->num_hosts)
return;
- GNUNET_free (rc->hc_handles);
- rc->hc_handles = NULL;
+ GNUNET_free (rc->hclist);
+ rc->hclist = NULL;
rc->h = rc->hosts[0];
rc->num_hosts--;
if (0 < rc->num_hosts)
GNUNET_free (rc->hosts);
rc->hosts = NULL;
}
+ parse_islands (rc);
GNUNET_OS_network_interfaces_list (netint_proc, rc);
if (NULL == rc->trusted_ip)
rc->trusted_ip = GNUNET_strdup ("127.0.0.1");
{
struct RunContext *rc;
char *topology;
+ struct CompatibilityCheckContext *hc;
struct GNUNET_TIME_Relative timeout;
unsigned long long random_links;
unsigned int hid;
}
if (0 != rc->num_hosts)
{
- rc->hc_handles =
- GNUNET_malloc (sizeof (struct GNUNET_TESTBED_HostHabitableCheckHandle *)
- * rc->num_hosts);
+ rc->hclist = GNUNET_malloc (sizeof (struct CompatibilityCheckContext)
+ * rc->num_hosts);
for (nhost = 0; nhost < rc->num_hosts; nhost++)
{
- if (NULL ==
- (rc->hc_handles[nhost] =
- GNUNET_TESTBED_is_host_habitable (rc->hosts[nhost], rc->cfg,
- &host_habitable_cb, rc)))
+ hc = &rc->hclist[nhost];
+ hc->index = nhost;
+ hc->rc = rc;
+ hc->h = GNUNET_TESTBED_is_host_habitable (rc->hosts[nhost], rc->cfg,
+ &host_habitable_cb, hc);
+ if (NULL == hc->h)
{
GNUNET_break (0);
for (nhost = 0; nhost < rc->num_hosts; nhost++)
- if (NULL != rc->hc_handles[nhost])
- GNUNET_TESTBED_is_host_habitable_cancel (rc->hc_handles[nhost]);
- GNUNET_free (rc->hc_handles);
- rc->hc_handles = NULL;
+ {
+ hc = &rc->hclist[nhost];
+ if (NULL != hc->h)
+ GNUNET_TESTBED_is_host_habitable_cancel (hc->h);
+ }
+ GNUNET_free (rc->hclist);
+ rc->hclist = NULL;
goto error_cleanup;
}
}