diff options
author | Sree Harsha Totakura <totakura@in.tum.de> | 2013-04-02 15:36:31 +0000 |
---|---|---|
committer | Sree Harsha Totakura <totakura@in.tum.de> | 2013-04-02 15:36:31 +0000 |
commit | fcb359dc93bdf9c891edcfb965013e19c61981cf (patch) | |
tree | a19218dabc4b1a5c72fbb7f54f6d4c83daa1d889 /src | |
parent | 690ce06e4dff30f4e337b93d285d9ad090f5b03b (diff) | |
download | gnunet-fcb359dc93bdf9c891edcfb965013e19c61981cf.tar.gz gnunet-fcb359dc93bdf9c891edcfb965013e19c61981cf.zip |
- manage services of peers (server)
Diffstat (limited to 'src')
-rw-r--r-- | src/testbed/Makefile.am | 1 | ||||
-rw-r--r-- | src/testbed/gnunet-service-testbed.c | 279 |
2 files changed, 280 insertions, 0 deletions
diff --git a/src/testbed/Makefile.am b/src/testbed/Makefile.am index 8b5cfbd9f..20056fba1 100644 --- a/src/testbed/Makefile.am +++ b/src/testbed/Makefile.am | |||
@@ -41,6 +41,7 @@ gnunet_service_testbed_LDADD = $(XLIB) \ | |||
41 | $(top_builddir)/src/transport/libgnunettransport.la \ | 41 | $(top_builddir)/src/transport/libgnunettransport.la \ |
42 | $(top_builddir)/src/testing/libgnunettesting.la \ | 42 | $(top_builddir)/src/testing/libgnunettesting.la \ |
43 | $(top_builddir)/src/testbed/libgnunettestbed.la \ | 43 | $(top_builddir)/src/testbed/libgnunettestbed.la \ |
44 | $(top_builddir)/src/arm/libgnunetarm.la \ | ||
44 | $(LTLIBINTL) -lz | 45 | $(LTLIBINTL) -lz |
45 | gnunet_service_testbed_DEPENDENCIES = \ | 46 | gnunet_service_testbed_DEPENDENCIES = \ |
46 | libgnunettestbed.la | 47 | libgnunettestbed.la |
diff --git a/src/testbed/gnunet-service-testbed.c b/src/testbed/gnunet-service-testbed.c index 81c17012d..e21879fab 100644 --- a/src/testbed/gnunet-service-testbed.c +++ b/src/testbed/gnunet-service-testbed.c | |||
@@ -1990,6 +1990,280 @@ handle_slave_get_config (void *cls, struct GNUNET_SERVER_Client *client, | |||
1990 | GNUNET_SERVER_receive_done (client, GNUNET_OK); | 1990 | GNUNET_SERVER_receive_done (client, GNUNET_OK); |
1991 | } | 1991 | } |
1992 | 1992 | ||
1993 | struct ManageServiceContext | ||
1994 | { | ||
1995 | |||
1996 | struct ManageServiceContext *next; | ||
1997 | |||
1998 | struct ManageServiceContext *prev; | ||
1999 | |||
2000 | struct GNUNET_ARM_Handle *ah; | ||
2001 | |||
2002 | struct Peer *peer; | ||
2003 | |||
2004 | struct GNUNET_SERVER_Client *client; | ||
2005 | |||
2006 | uint64_t op_id; | ||
2007 | |||
2008 | uint8_t start; | ||
2009 | |||
2010 | uint8_t expired; | ||
2011 | |||
2012 | }; | ||
2013 | |||
2014 | static struct ManageServiceContext *mctx_head; | ||
2015 | |||
2016 | static struct ManageServiceContext *mctx_tail; | ||
2017 | |||
2018 | static void | ||
2019 | cleanup_mctx (struct ManageServiceContext *mctx) | ||
2020 | { | ||
2021 | mctx->expired = GNUNET_YES; | ||
2022 | GNUNET_CONTAINER_DLL_remove (mctx_head, mctx_tail, mctx); | ||
2023 | GNUNET_SERVER_client_drop (mctx->client); | ||
2024 | GNUNET_ARM_disconnect_and_free (mctx->ah); | ||
2025 | GNUNET_assert (0 < mctx->peer->reference_cnt); | ||
2026 | mctx->peer->reference_cnt--; | ||
2027 | if ( (GNUNET_YES == mctx->peer->destroy_flag) | ||
2028 | && (0 == mctx->peer->reference_cnt) ) | ||
2029 | GST_destroy_peer (mctx->peer); | ||
2030 | GNUNET_free (mctx); | ||
2031 | } | ||
2032 | |||
2033 | static void | ||
2034 | free_mctxq () | ||
2035 | { | ||
2036 | while (NULL != mctx_head) | ||
2037 | cleanup_mctx (mctx_head); | ||
2038 | } | ||
2039 | |||
2040 | static const char * | ||
2041 | arm_req_string (enum GNUNET_ARM_RequestStatus rs) | ||
2042 | { | ||
2043 | switch (rs) | ||
2044 | { | ||
2045 | case GNUNET_ARM_REQUEST_SENT_OK: | ||
2046 | return _("Message was sent successfully"); | ||
2047 | case GNUNET_ARM_REQUEST_CONFIGURATION_ERROR: | ||
2048 | return _("Misconfiguration (can't connect to the ARM service)"); | ||
2049 | case GNUNET_ARM_REQUEST_DISCONNECTED: | ||
2050 | return _("We disconnected from ARM before we could send a request"); | ||
2051 | case GNUNET_ARM_REQUEST_BUSY: | ||
2052 | return _("ARM API is busy"); | ||
2053 | case GNUNET_ARM_REQUEST_TOO_LONG: | ||
2054 | return _("Request doesn't fit into a message"); | ||
2055 | case GNUNET_ARM_REQUEST_TIMEOUT: | ||
2056 | return _("Request timed out"); | ||
2057 | } | ||
2058 | return _("Unknown request status"); | ||
2059 | } | ||
2060 | |||
2061 | static const char * | ||
2062 | arm_ret_string (enum GNUNET_ARM_Result result) | ||
2063 | { | ||
2064 | switch (result) | ||
2065 | { | ||
2066 | case GNUNET_ARM_RESULT_STOPPED: | ||
2067 | return _("%s is stopped"); | ||
2068 | case GNUNET_ARM_RESULT_STARTING: | ||
2069 | return _("%s is starting"); | ||
2070 | case GNUNET_ARM_RESULT_STOPPING: | ||
2071 | return _("%s is stopping"); | ||
2072 | case GNUNET_ARM_RESULT_IS_STARTING_ALREADY: | ||
2073 | return _("%s is starting already"); | ||
2074 | case GNUNET_ARM_RESULT_IS_STOPPING_ALREADY: | ||
2075 | return _("%s is stopping already"); | ||
2076 | case GNUNET_ARM_RESULT_IS_STARTED_ALREADY: | ||
2077 | return _("%s is started already"); | ||
2078 | case GNUNET_ARM_RESULT_IS_STOPPED_ALREADY: | ||
2079 | return _("%s is stopped already"); | ||
2080 | case GNUNET_ARM_RESULT_IS_NOT_KNOWN: | ||
2081 | return _("%s service is not known to ARM"); | ||
2082 | case GNUNET_ARM_RESULT_START_FAILED: | ||
2083 | return _("%s service failed to start"); | ||
2084 | case GNUNET_ARM_RESULT_IN_SHUTDOWN: | ||
2085 | return _("%s service can't be started because ARM is shutting down"); | ||
2086 | } | ||
2087 | return _("Unknown result code."); | ||
2088 | } | ||
2089 | |||
2090 | static void | ||
2091 | service_manage_result_cb (void *cls, struct GNUNET_ARM_Handle *arm, | ||
2092 | enum GNUNET_ARM_RequestStatus rs, | ||
2093 | const char *service, enum GNUNET_ARM_Result result) | ||
2094 | { | ||
2095 | struct ManageServiceContext *mctx = cls; | ||
2096 | char *emsg; | ||
2097 | |||
2098 | emsg = NULL; | ||
2099 | if (GNUNET_YES == mctx->expired) | ||
2100 | return; | ||
2101 | if (GNUNET_ARM_REQUEST_SENT_OK != rs) | ||
2102 | { | ||
2103 | GNUNET_asprintf (&emsg, "Error communicating with Peer %u's ARM: %s", | ||
2104 | mctx->peer->id, arm_req_string (rs)); | ||
2105 | goto ret; | ||
2106 | } | ||
2107 | if (1 == mctx->start) | ||
2108 | goto service_start_check; | ||
2109 | if (! ((GNUNET_ARM_RESULT_STOPPED == result) | ||
2110 | || (GNUNET_ARM_RESULT_STOPPING == result) | ||
2111 | || (GNUNET_ARM_RESULT_IS_STOPPING_ALREADY == result) | ||
2112 | || (GNUNET_ARM_RESULT_IS_STOPPED_ALREADY == result)) ) | ||
2113 | { | ||
2114 | /* stopping a service failed */ | ||
2115 | GNUNET_asprintf (&emsg, arm_ret_string (result), service); | ||
2116 | goto ret; | ||
2117 | } | ||
2118 | /* service stopped successfully */ | ||
2119 | goto ret; | ||
2120 | |||
2121 | service_start_check: | ||
2122 | if (! ((GNUNET_ARM_RESULT_STARTING == result) | ||
2123 | || (GNUNET_ARM_RESULT_IS_STARTING_ALREADY == result) | ||
2124 | || (GNUNET_ARM_RESULT_IS_STARTED_ALREADY == result)) ) | ||
2125 | { | ||
2126 | /* starting a service failed */ | ||
2127 | GNUNET_asprintf (&emsg, arm_ret_string (result), service); | ||
2128 | goto ret; | ||
2129 | } | ||
2130 | /* service started successfully */ | ||
2131 | |||
2132 | ret: | ||
2133 | if (NULL != emsg) | ||
2134 | { | ||
2135 | LOG_DEBUG ("%s\n", emsg); | ||
2136 | GST_send_operation_fail_msg (mctx->client, mctx->op_id, emsg); | ||
2137 | } | ||
2138 | else | ||
2139 | send_operation_success_msg (mctx->client, mctx->op_id); | ||
2140 | GNUNET_free (emsg); | ||
2141 | cleanup_mctx (mctx); | ||
2142 | } | ||
2143 | |||
2144 | static void | ||
2145 | handle_manage_peer_service (void *cls, struct GNUNET_SERVER_Client *client, | ||
2146 | const struct GNUNET_MessageHeader *message) | ||
2147 | { | ||
2148 | const struct GNUNET_TESTBED_ManagePeerServiceMessage *msg; | ||
2149 | const char* service; | ||
2150 | struct Peer *peer; | ||
2151 | char *emsg; | ||
2152 | struct GNUNET_ARM_Handle *ah; | ||
2153 | struct ManageServiceContext *mctx; | ||
2154 | struct ForwardedOperationContext *fopc; | ||
2155 | uint64_t op_id; | ||
2156 | uint32_t peer_id; | ||
2157 | uint16_t msize; | ||
2158 | |||
2159 | |||
2160 | msize = ntohs (message->size); | ||
2161 | if (msize <= sizeof (struct GNUNET_TESTBED_ManagePeerServiceMessage)) | ||
2162 | { | ||
2163 | GNUNET_break_op (0); | ||
2164 | GNUNET_SERVER_receive_done (client, GNUNET_SYSERR); | ||
2165 | return; | ||
2166 | } | ||
2167 | msg = (const struct GNUNET_TESTBED_ManagePeerServiceMessage *) message; | ||
2168 | service = (const char *) &msg[1]; | ||
2169 | if ('\0' != service[msize - sizeof | ||
2170 | (struct GNUNET_TESTBED_ManagePeerServiceMessage) - 1]) | ||
2171 | { | ||
2172 | GNUNET_break_op (0); | ||
2173 | GNUNET_SERVER_receive_done (client, GNUNET_SYSERR); | ||
2174 | return; | ||
2175 | } | ||
2176 | if (1 < msg->start) | ||
2177 | { | ||
2178 | GNUNET_break_op (0); | ||
2179 | GNUNET_SERVER_receive_done (client, GNUNET_SYSERR); | ||
2180 | return; | ||
2181 | } | ||
2182 | peer_id = ntohl (msg->peer_id); | ||
2183 | op_id = GNUNET_ntohll (msg->operation_id); | ||
2184 | LOG_DEBUG ("Received request to manage service %s on peer %u\n", | ||
2185 | service, (unsigned int) peer_id); | ||
2186 | if ((GST_peer_list_size <= peer_id) | ||
2187 | || (NULL == (peer = GST_peer_list[peer_id]))) | ||
2188 | { | ||
2189 | GNUNET_asprintf (&emsg, "Asked to manage service of a non existent peer " | ||
2190 | "with id: %u", peer_id); | ||
2191 | goto err_ret; | ||
2192 | } | ||
2193 | if (0 == strcasecmp ("arm", service)) | ||
2194 | { | ||
2195 | emsg = GNUNET_strdup ("Cannot start/stop peer's ARM service. " | ||
2196 | "Use peer start/stop for that"); | ||
2197 | goto err_ret; | ||
2198 | } | ||
2199 | if (GNUNET_YES == peer->is_remote) | ||
2200 | { | ||
2201 | /* Forward the destory message to sub controller */ | ||
2202 | fopc = GNUNET_malloc (sizeof (struct ForwardedOperationContext)); | ||
2203 | GNUNET_SERVER_client_keep (client); | ||
2204 | fopc->client = client; | ||
2205 | fopc->cls = peer; | ||
2206 | fopc->type = OP_MANAGE_SERVICE; | ||
2207 | fopc->operation_id = op_id; | ||
2208 | fopc->opc = | ||
2209 | GNUNET_TESTBED_forward_operation_msg_ (peer->details.remote. | ||
2210 | slave->controller, | ||
2211 | fopc->operation_id, &msg->header, | ||
2212 | &GST_forwarded_operation_reply_relay, | ||
2213 | fopc); | ||
2214 | fopc->timeout_task = | ||
2215 | GNUNET_SCHEDULER_add_delayed (GST_timeout, &GST_forwarded_operation_timeout, | ||
2216 | fopc); | ||
2217 | GNUNET_CONTAINER_DLL_insert_tail (fopcq_head, fopcq_tail, fopc); | ||
2218 | GNUNET_SERVER_receive_done (client, GNUNET_OK); | ||
2219 | return; | ||
2220 | } | ||
2221 | if ((0 != peer->reference_cnt) | ||
2222 | && ( (0 == strcasecmp ("core", service)) | ||
2223 | || (0 == strcasecmp ("transport", service)) ) ) | ||
2224 | { | ||
2225 | GNUNET_asprintf (&emsg, "Cannot stop %s service of peer with id: %u " | ||
2226 | "since it is required by existing operations", | ||
2227 | service, peer_id); | ||
2228 | goto err_ret; | ||
2229 | } | ||
2230 | ah = GNUNET_ARM_connect (peer->details.local.cfg, NULL, NULL); | ||
2231 | if (NULL == ah) | ||
2232 | { | ||
2233 | GNUNET_asprintf (&emsg, | ||
2234 | "Cannot connect to ARM service of peer with id: %u", | ||
2235 | peer_id); | ||
2236 | goto err_ret; | ||
2237 | } | ||
2238 | mctx = GNUNET_malloc (sizeof (struct ManageServiceContext)); | ||
2239 | mctx->peer = peer; | ||
2240 | peer->reference_cnt++; | ||
2241 | mctx->op_id = op_id; | ||
2242 | mctx->ah = ah; | ||
2243 | GNUNET_SERVER_client_keep (client); | ||
2244 | mctx->client = client; | ||
2245 | mctx->start = msg->start; | ||
2246 | GNUNET_CONTAINER_DLL_insert_tail (mctx_head, mctx_tail, mctx); | ||
2247 | if (1 == mctx->start) | ||
2248 | GNUNET_ARM_request_service_start (mctx->ah, service, | ||
2249 | GNUNET_OS_INHERIT_STD_ERR, | ||
2250 | GST_timeout, | ||
2251 | service_manage_result_cb, | ||
2252 | mctx); | ||
2253 | else | ||
2254 | GNUNET_ARM_request_service_stop (mctx->ah, service, | ||
2255 | GST_timeout, | ||
2256 | service_manage_result_cb, | ||
2257 | mctx); | ||
2258 | GNUNET_SERVER_receive_done (client, GNUNET_OK); | ||
2259 | return; | ||
2260 | |||
2261 | err_ret: | ||
2262 | LOG (GNUNET_ERROR_TYPE_ERROR, "%s\n", emsg); | ||
2263 | GST_send_operation_fail_msg (client, op_id, emsg); | ||
2264 | GNUNET_free (emsg); | ||
2265 | GNUNET_SERVER_receive_done (client, GNUNET_OK); | ||
2266 | } | ||
1993 | 2267 | ||
1994 | /** | 2268 | /** |
1995 | * Clears the forwarded operations queue | 2269 | * Clears the forwarded operations queue |
@@ -2028,6 +2302,7 @@ clear_fopcq () | |||
2028 | case OP_OVERLAY_CONNECT: | 2302 | case OP_OVERLAY_CONNECT: |
2029 | case OP_LINK_CONTROLLERS: | 2303 | case OP_LINK_CONTROLLERS: |
2030 | case OP_GET_SLAVE_CONFIG: | 2304 | case OP_GET_SLAVE_CONFIG: |
2305 | case OP_MANAGE_SERVICE: | ||
2031 | break; | 2306 | break; |
2032 | case OP_FORWARDED: | 2307 | case OP_FORWARDED: |
2033 | GNUNET_assert (0); | 2308 | GNUNET_assert (0); |
@@ -2169,6 +2444,7 @@ handle_shutdown_peers (void *cls, struct GNUNET_SERVER_Client *client, | |||
2169 | msg = (const struct GNUNET_TESTBED_ShutdownPeersMessage *) message; | 2444 | msg = (const struct GNUNET_TESTBED_ShutdownPeersMessage *) message; |
2170 | LOG_DEBUG ("Received SHUTDOWN_PEERS\n"); | 2445 | LOG_DEBUG ("Received SHUTDOWN_PEERS\n"); |
2171 | /* Stop and destroy all peers */ | 2446 | /* Stop and destroy all peers */ |
2447 | free_mctxq (); | ||
2172 | GST_free_occq (); | 2448 | GST_free_occq (); |
2173 | GST_free_roccq (); | 2449 | GST_free_roccq (); |
2174 | clear_fopcq (); | 2450 | clear_fopcq (); |
@@ -2310,6 +2586,7 @@ shutdown_task (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc) | |||
2310 | GNUNET_CONTAINER_DLL_remove (lcfq_head, lcfq_tail, lcfq); | 2586 | GNUNET_CONTAINER_DLL_remove (lcfq_head, lcfq_tail, lcfq); |
2311 | GNUNET_free (lcfq); | 2587 | GNUNET_free (lcfq); |
2312 | } | 2588 | } |
2589 | free_mctxq (); | ||
2313 | GST_free_occq (); | 2590 | GST_free_occq (); |
2314 | GST_free_roccq (); | 2591 | GST_free_roccq (); |
2315 | /* Clear peer list */ | 2592 | /* Clear peer list */ |
@@ -2435,6 +2712,8 @@ testbed_run (void *cls, struct GNUNET_SERVER_Handle *server, | |||
2435 | sizeof (struct GNUNET_TESTBED_OverlayConnectMessage)}, | 2712 | sizeof (struct GNUNET_TESTBED_OverlayConnectMessage)}, |
2436 | {&GST_handle_remote_overlay_connect, NULL, | 2713 | {&GST_handle_remote_overlay_connect, NULL, |
2437 | GNUNET_MESSAGE_TYPE_TESTBED_REMOTE_OVERLAY_CONNECT, 0}, | 2714 | GNUNET_MESSAGE_TYPE_TESTBED_REMOTE_OVERLAY_CONNECT, 0}, |
2715 | {&handle_manage_peer_service, NULL, | ||
2716 | GNUNET_MESSAGE_TYPE_TESTBED_MANAGE_PEER_SERVICE, 0}, | ||
2438 | {&handle_slave_get_config, NULL, | 2717 | {&handle_slave_get_config, NULL, |
2439 | GNUNET_MESSAGE_TYPE_TESTBED_GET_SLAVE_CONFIGURATION, | 2718 | GNUNET_MESSAGE_TYPE_TESTBED_GET_SLAVE_CONFIGURATION, |
2440 | sizeof (struct GNUNET_TESTBED_SlaveGetConfigurationMessage)}, | 2719 | sizeof (struct GNUNET_TESTBED_SlaveGetConfigurationMessage)}, |