From 14c98ff17a8b1e4db1e6445f6116b7be5b4b8934 Mon Sep 17 00:00:00 2001 From: Sree Harsha Totakura Date: Fri, 17 Aug 2012 14:54:29 +0000 Subject: controller link as operation --- src/include/gnunet_testbed_service.h | 6 +- src/testbed/gnunet-service-testbed.c | 91 +++++++++++++++++++++------ src/testbed/test_testbed_api_controllerlink.c | 34 +++++++--- src/testbed/testbed.h | 5 ++ src/testbed/testbed_api.c | 90 ++++++++++++++++++++------ src/testbed/testbed_api.h | 17 ++--- src/testbed/testbed_api_peers.c | 6 +- 7 files changed, 188 insertions(+), 61 deletions(-) diff --git a/src/include/gnunet_testbed_service.h b/src/include/gnunet_testbed_service.h index 0236d82af..c3635ed5c 100644 --- a/src/include/gnunet_testbed_service.h +++ b/src/include/gnunet_testbed_service.h @@ -574,8 +574,9 @@ GNUNET_TESTBED_cancel_registration (struct GNUNET_TESTBED_HostRegistrationHandle * @param is_subordinate GNUNET_YES if the controller at delegated_host should * be started by the master controller; GNUNET_NO if we are just * allowed to use the slave via TCP/IP + * @return the operation handle */ -void +struct GNUNET_TESTBED_Operation * GNUNET_TESTBED_controller_link (struct GNUNET_TESTBED_Controller *master, struct GNUNET_TESTBED_Host *delegated_host, struct GNUNET_TESTBED_Host *slave_host, @@ -597,8 +598,9 @@ GNUNET_TESTBED_controller_link (struct GNUNET_TESTBED_Controller *master, * @param is_subordinate GNUNET_YES if the controller at delegated_host should * be started by the master controller; GNUNET_NO if we are just * allowed to use the slave via TCP/IP + * @return the operation handle */ -void +struct GNUNET_TESTBED_Operation * GNUNET_TESTBED_controller_link_2 (struct GNUNET_TESTBED_Controller *master, struct GNUNET_TESTBED_Host *delegated_host, struct GNUNET_TESTBED_Host *slave_host, diff --git a/src/testbed/gnunet-service-testbed.c b/src/testbed/gnunet-service-testbed.c index c9f8436e6..07a8aa714 100644 --- a/src/testbed/gnunet-service-testbed.c +++ b/src/testbed/gnunet-service-testbed.c @@ -469,6 +469,29 @@ struct ForwardedOperationContext }; +/** + * Context information used while linking controllers + */ +struct LinkControllersContext +{ + /** + * The client which initiated the link controller operation + */ + struct GNUNET_SERVER_Client *client; + + /** + * The ID of the operation + */ + uint64_t operation_id; + + /** + * Pointer to the slave handle if we are directly starting/connecting to the controller + */ + struct Slave *slave; +}; + + + /** * The master context; generated with the first INIT message */ @@ -977,6 +1000,29 @@ slave_event_callback(void *cls, } +/** + * Function to send generic operation success message to given client + * + * @param client the client to send the message to + * @param operation_id the id of the operation which was successful + */ +static void +send_operation_success_msg (struct GNUNET_SERVER_Client *client, + uint64_t operation_id) +{ + struct GNUNET_TESTBED_GenericOperationSuccessEventMessage *msg; + uint16_t msize; + + msize = sizeof (struct GNUNET_TESTBED_GenericOperationSuccessEventMessage); + msg = GNUNET_malloc (msize); + msg->header.size = htons (msize); + msg->header.type = htons (GNUNET_MESSAGE_TYPE_TESTBED_GENERICOPSUCCESS); + msg->operation_id = GNUNET_htonll (operation_id); + msg->event_type = htonl (GNUNET_TESTBED_ET_OPERATION_FINISHED); + queue_message (client, &msg->header); +} + + /** * Callback to signal successfull startup of the controller process * @@ -991,20 +1037,27 @@ slave_status_callback (void *cls, const struct GNUNET_CONFIGURATION_Handle *cfg, int status) { - struct Slave *slave = cls; + struct LinkControllersContext *lcc = cls; if (GNUNET_SYSERR == status) { - slave->controller_proc = NULL; + lcc->slave->controller_proc = NULL; LOG (GNUNET_ERROR_TYPE_WARNING, "Unexpected slave shutdown\n"); GNUNET_SCHEDULER_shutdown (); /* We too shutdown */ return; } - slave->controller = - GNUNET_TESTBED_controller_connect (cfg, host_list[slave->host_id], + lcc->slave->controller = + GNUNET_TESTBED_controller_connect (cfg, host_list[lcc->slave->host_id], master_context->event_mask, - &slave_event_callback, slave); + &slave_event_callback, lcc->slave); + if (NULL != lcc->slave->controller) + send_operation_success_msg (lcc->client, lcc->operation_id); + else + send_operation_fail_msg (lcc->client, lcc->operation_id, + "Could not connect to delegated controller"); + GNUNET_SERVER_client_drop (lcc->client); + GNUNET_free (lcc); } @@ -1299,7 +1352,6 @@ handle_link_controllers (void *cls, if (slave_host_id == master_context->host_id) /* Link from us */ { struct Slave *slave; - if ((delegated_host_id < slave_list_size) && (NULL != slave_list[delegated_host_id])) /* We have already added */ { @@ -1344,20 +1396,32 @@ handle_link_controllers (void *cls, } slave = GNUNET_malloc (sizeof (struct Slave)); slave->host_id = delegated_host_id; - slave_list_add (slave); + slave_list_add (slave); + if (1 == msg->is_subordinate) { + struct LinkControllersContext *lcc; + lcc = GNUNET_malloc (sizeof (struct LinkControllersContext)); + lcc->operation_id = GNUNET_ntohll (msg->operation_id); + GNUNET_SERVER_client_keep (client); + lcc->client = client; + lcc->slave = slave; slave->controller_proc = GNUNET_TESTBED_controller_start (master_context->master_ip, host_list[slave->host_id], cfg, &slave_status_callback, - slave); + lcc); } else { slave->controller = GNUNET_TESTBED_controller_connect (cfg, host_list[slave->host_id], master_context->event_mask, &slave_event_callback, slave); + if (NULL != slave->controller) + send_operation_success_msg (client, GNUNET_ntohll (msg->operation_id)); + else + send_operation_fail_msg (client, GNUNET_ntohll (msg->operation_id), + "Could not connect to delegated controller"); } GNUNET_CONFIGURATION_destroy (cfg); new_route = GNUNET_malloc (sizeof (struct Route)); @@ -1594,10 +1658,8 @@ handle_peer_destroy (void *cls, const struct GNUNET_MessageHeader *message) { const struct GNUNET_TESTBED_PeerDestroyMessage *msg; - struct GNUNET_TESTBED_GenericOperationSuccessEventMessage *reply; struct Peer *peer; uint32_t peer_id; - uint16_t reply_size; msg = (const struct GNUNET_TESTBED_PeerDestroyMessage *) message; peer_id = ntohl (msg->peer_id); @@ -1622,14 +1684,7 @@ handle_peer_destroy (void *cls, GNUNET_CONFIGURATION_destroy (peer->details.local.cfg); peer_list_remove (peer); GNUNET_free (peer); - reply_size = - sizeof (struct GNUNET_TESTBED_GenericOperationSuccessEventMessage); - reply = GNUNET_malloc (reply_size); - reply->header.type = htons (GNUNET_MESSAGE_TYPE_TESTBED_GENERICOPSUCCESS); - reply->header.size = htons (reply_size); - reply->operation_id = msg->operation_id; - reply->event_type = htonl (GNUNET_TESTBED_ET_OPERATION_FINISHED); - queue_message (client, &reply->header); + send_operation_success_msg (client, GNUNET_ntohll (msg->operation_id)); GNUNET_SERVER_receive_done (client, GNUNET_OK); } diff --git a/src/testbed/test_testbed_api_controllerlink.c b/src/testbed/test_testbed_api_controllerlink.c index bda27d8cf..06b0b8029 100644 --- a/src/testbed/test_testbed_api_controllerlink.c +++ b/src/testbed/test_testbed_api_controllerlink.c @@ -104,6 +104,11 @@ static struct GNUNET_CONFIGURATION_Handle *cfg; */ static GNUNET_SCHEDULER_TaskIdentifier abort_task; +/** + * Operation handle for linking controllers + */ +static struct GNUNET_TESTBED_Operation *op; + /** * Event mask */ @@ -167,7 +172,25 @@ do_abort (void *cls, const const struct GNUNET_SCHEDULER_TaskContext *tc) static void controller_cb(void *cls, const struct GNUNET_TESTBED_EventInformation *event) { - GNUNET_assert (0); + switch (result) + { + case SLAVE1_REGISTERED: + GNUNET_assert (NULL != event); + GNUNET_assert (GNUNET_TESTBED_ET_OPERATION_FINISHED == event->type); + GNUNET_assert (event->details.operation_finished.operation == op); + GNUNET_assert (NULL == event->details.operation_finished.op_cls); + GNUNET_assert (NULL == event->details.operation_finished.emsg); + GNUNET_assert (GNUNET_TESTBED_PIT_GENERIC == + event->details.operation_finished.pit); + GNUNET_assert (NULL == event->details.operation_finished.op_result.generic); + GNUNET_TESTBED_operation_done (op); + op = NULL; + result = SUCCESS; + GNUNET_SCHEDULER_add_now (&do_shutdown, NULL); + break; + default: + GNUNET_assert (0); + } } @@ -188,11 +211,8 @@ registration_cont (void *cls, const char *emsg) GNUNET_assert (NULL != mc); result = SLAVE1_REGISTERED; GNUNET_assert (NULL != cfg); - GNUNET_TESTBED_controller_link (mc, slave, NULL, cfg, GNUNET_YES); - result = SUCCESS; - GNUNET_SCHEDULER_add_delayed - (GNUNET_TIME_relative_multiply (GNUNET_TIME_UNIT_SECONDS, 10), - &do_shutdown, NULL); + op = GNUNET_TESTBED_controller_link (mc, slave, NULL, cfg, GNUNET_YES); + GNUNET_assert (NULL != op); break; case INIT: case SUCCESS: @@ -256,7 +276,7 @@ run (void *cls, char *const *args, const char *cfgfile, cp = GNUNET_TESTBED_controller_start ("127.0.0.1", host, cfg, status_cb, NULL); abort_task = GNUNET_SCHEDULER_add_delayed - (GNUNET_TIME_relative_multiply (GNUNET_TIME_UNIT_MINUTES, 30), + (GNUNET_TIME_relative_multiply (GNUNET_TIME_UNIT_MINUTES, 5), &do_abort, NULL); } diff --git a/src/testbed/testbed.h b/src/testbed/testbed.h index b6a0e30cc..c7848135d 100644 --- a/src/testbed/testbed.h +++ b/src/testbed/testbed.h @@ -165,6 +165,11 @@ struct GNUNET_TESTBED_ControllerLinkMessage */ uint32_t delegated_host_id GNUNET_PACKED; + /** + * The id of the operation which created this message + */ + uint64_t operation_id GNUNET_PACKED; + /** * Which host is responsible for managing the delegation? NBO */ diff --git a/src/testbed/testbed_api.c b/src/testbed/testbed_api.c index afac22fba..f2431c630 100644 --- a/src/testbed/testbed_api.c +++ b/src/testbed/testbed_api.c @@ -285,25 +285,26 @@ handle_opsuccess (struct GNUNET_TESTBED_Controller *c, { case OP_PEER_DESTROY: { - struct GNUNET_TESTBED_Peer *peer; - - if (NULL != event) - { - event->details.operation_finished.operation = opc->op; - event->details.operation_finished.op_cls = NULL; - event->details.operation_finished.emsg = NULL; - event->details.operation_finished.pit = GNUNET_TESTBED_PIT_GENERIC; - event->details.operation_finished.op_result.generic = NULL; - } + struct GNUNET_TESTBED_Peer *peer; peer = opc->data; GNUNET_free (peer); opc->data = NULL; //PEERDESTROYDATA } break; + case OP_LINK_CONTROLLERS: + break; default: GNUNET_assert (0); } + if (NULL != event) + { + event->details.operation_finished.operation = opc->op; + event->details.operation_finished.op_cls = NULL; + event->details.operation_finished.emsg = NULL; + event->details.operation_finished.pit = GNUNET_TESTBED_PIT_GENERIC; + event->details.operation_finished.op_result.generic = NULL; + } GNUNET_CONTAINER_DLL_remove (opc->c->ocq_head, opc->c->ocq_tail, opc); opc->state = OPC_STATE_FINISHED; if (NULL != event) @@ -952,6 +953,45 @@ helper_exp_cb (void *cls) } +/** + * Function to call to start a link-controllers type operation once all queues + * the operation is part of declare that the operation can be activated. + * + * @param cls the closure from GNUNET_TESTBED_operation_create_() + */ +static void +opstart_link_controllers (void *cls) +{ + struct OperationContext *opc = cls; + struct GNUNET_TESTBED_ControllerLinkMessage *msg; + + GNUNET_assert (NULL != opc->data); + msg = opc->data; + opc->data = NULL; + opc->state = OPC_STATE_STARTED; + GNUNET_CONTAINER_DLL_insert_tail (opc->c->ocq_head, opc->c->ocq_tail, opc); + GNUNET_TESTBED_queue_message_ (opc->c, &msg->header); +} + + +/** + * Callback which will be called when link-controllers type operation is released + * + * @param cls the closure from GNUNET_TESTBED_operation_create_() + */ +static void +oprelease_link_controllers (void *cls) +{ + struct OperationContext *opc = cls; + + if (OPC_STATE_INIT == opc->state) + GNUNET_free (opc->data); + if (OPC_STATE_STARTED == opc->state) + GNUNET_CONTAINER_DLL_remove (opc->c->ocq_head, opc->c->ocq_tail, opc); + GNUNET_free (opc); +} + + /** * Starts a controller process at the host. FIXME: add controller start callback * with the configuration with which the controller is started @@ -1320,7 +1360,7 @@ GNUNET_TESTBED_cancel_registration (struct GNUNET_TESTBED_HostRegistrationHandle * be started by the master controller; GNUNET_NO if we are just * allowed to use the slave via TCP/IP */ -void +struct GNUNET_TESTBED_Operation * GNUNET_TESTBED_controller_link_2 (struct GNUNET_TESTBED_Controller *master, struct GNUNET_TESTBED_Host *delegated_host, struct GNUNET_TESTBED_Host *slave_host, @@ -1329,6 +1369,7 @@ GNUNET_TESTBED_controller_link_2 (struct GNUNET_TESTBED_Controller *master, size_t scfg_size, int is_subordinate) { + struct OperationContext *opc; struct GNUNET_TESTBED_ControllerLinkMessage *msg; uint16_t msg_size; @@ -1347,7 +1388,17 @@ GNUNET_TESTBED_controller_link_2 (struct GNUNET_TESTBED_Controller *master, msg->config_size = htons ((uint16_t) scfg_size); msg->is_subordinate = (GNUNET_YES == is_subordinate) ? 1 : 0; memcpy (&msg[1], sxcfg, sxcfg_size); - GNUNET_TESTBED_queue_message_ (master, (struct GNUNET_MessageHeader *) msg); + opc = GNUNET_malloc (sizeof (struct OperationContext)); + opc->c = master; + opc->data = msg; + opc->type = OP_LINK_CONTROLLERS; + opc->id = master->operation_counter++; + opc->state = OPC_STATE_INIT; + msg->operation_id = GNUNET_htonll (opc->id); + opc->op = GNUNET_TESTBED_operation_create_ (opc, &opstart_link_controllers, + &oprelease_link_controllers); + GNUNET_TESTBED_operation_queue_insert_ (master->opq_peer_create, opc->op); + return opc->op; } @@ -1395,23 +1446,25 @@ GNUNET_TESTBED_compress_config_ (const char *config, size_t size, * @param is_subordinate GNUNET_YES if the slave should be started (and stopped) * by the master controller; GNUNET_NO if we are just * allowed to use the slave via TCP/IP + * @return the operation handle */ -void +struct GNUNET_TESTBED_Operation * GNUNET_TESTBED_controller_link (struct GNUNET_TESTBED_Controller *master, struct GNUNET_TESTBED_Host *delegated_host, struct GNUNET_TESTBED_Host *slave_host, const struct GNUNET_CONFIGURATION_Handle *slave_cfg, int is_subordinate) { + struct GNUNET_TESTBED_Operation *op; char *config; char *cconfig; size_t cc_size; size_t config_size; - GNUNET_assert (GNUNET_YES == + GNUNET_assert (GNUNET_YES == GNUNET_TESTBED_is_host_registered_ (delegated_host, master)); if ((NULL != slave_host) && (0 != GNUNET_TESTBED_host_get_id_ (slave_host))) - GNUNET_assert (GNUNET_YES == + GNUNET_assert (GNUNET_YES == GNUNET_TESTBED_is_host_registered_ (slave_host, master)); config = GNUNET_CONFIGURATION_serialize (slave_cfg, &config_size); cc_size = GNUNET_TESTBED_compress_config_ (config, config_size, &cconfig); @@ -1419,10 +1472,11 @@ GNUNET_TESTBED_controller_link (struct GNUNET_TESTBED_Controller *master, GNUNET_assert ((UINT16_MAX - sizeof (struct GNUNET_TESTBED_ControllerLinkMessage)) >= cc_size); /* Configuration doesn't fit in 1 message */ - GNUNET_TESTBED_controller_link_2 (master, delegated_host, slave_host, + op = GNUNET_TESTBED_controller_link_2 (master, delegated_host, slave_host, (const char *) cconfig, cc_size, config_size, is_subordinate); GNUNET_free (cconfig); + return op; } @@ -1495,9 +1549,6 @@ GNUNET_TESTBED_create_helper_init_msg_ (const char *cname, void GNUNET_TESTBED_operation_cancel (struct GNUNET_TESTBED_Operation *operation) { - GNUNET_CONTAINER_DLL_remove (operation->controller->op_head, - operation->controller->op_tail, - operation); GNUNET_TESTBED_operation_done (operation); } @@ -1522,6 +1573,7 @@ GNUNET_TESTBED_operation_done (struct GNUNET_TESTBED_Operation *operation) case OP_PEER_STOP: case OP_PEER_INFO: case OP_OVERLAY_CONNECT: + case OP_LINK_CONTROLLERS: GNUNET_TESTBED_operation_release_ (operation); return; default: diff --git a/src/testbed/testbed_api.h b/src/testbed/testbed_api.h index a8cb383fa..625f3d1f6 100644 --- a/src/testbed/testbed_api.h +++ b/src/testbed/testbed_api.h @@ -66,7 +66,12 @@ enum OperationType /** * Forwarded operation */ - OP_FORWARDED + OP_FORWARDED, + + /** + * Link controllers operation + */ + OP_LINK_CONTROLLERS, }; @@ -259,16 +264,6 @@ struct GNUNET_TESTBED_Controller */ struct GNUNET_TESTBED_HostRegistrationHandle *rh; - /** - * The head of the operation queue (FIXME: Remove, use ocq) - */ - struct GNUNET_TESTBED_Operation *op_head; - - /** - * The tail of the operation queue (FIXME: Remove, use ocq) - */ - struct GNUNET_TESTBED_Operation *op_tail; - /** * The head of the opeartion context queue */ diff --git a/src/testbed/testbed_api_peers.c b/src/testbed/testbed_api_peers.c index 380190578..51ef66bec 100644 --- a/src/testbed/testbed_api_peers.c +++ b/src/testbed/testbed_api_peers.c @@ -69,10 +69,8 @@ opstart_peer_create (void *cls) msg->host_id = htonl (GNUNET_TESTBED_host_get_id_ (data->peer->host)); msg->peer_id = htonl (data->peer->unique_id); msg->config_size = htonl (c_size); - GNUNET_CONTAINER_DLL_insert_tail (opc->c->ocq_head, - opc->c->ocq_tail, opc); - GNUNET_TESTBED_queue_message_ (opc->c, - (struct GNUNET_MessageHeader *) msg); + GNUNET_CONTAINER_DLL_insert_tail (opc->c->ocq_head, opc->c->ocq_tail, opc); + GNUNET_TESTBED_queue_message_ (opc->c, &msg->header); }; -- cgit v1.2.3