diff options
Diffstat (limited to 'src/arm/gnunet-service-arm.c')
-rw-r--r-- | src/arm/gnunet-service-arm.c | 101 |
1 files changed, 81 insertions, 20 deletions
diff --git a/src/arm/gnunet-service-arm.c b/src/arm/gnunet-service-arm.c index e02314b91..b30ae518e 100644 --- a/src/arm/gnunet-service-arm.c +++ b/src/arm/gnunet-service-arm.c | |||
@@ -164,6 +164,11 @@ struct ServiceList { | |||
164 | struct GNUNET_TIME_Relative backoff; | 164 | struct GNUNET_TIME_Relative backoff; |
165 | 165 | ||
166 | /** | 166 | /** |
167 | * Absolute time at which the process was (re-)started last. | ||
168 | */ | ||
169 | struct GNUNET_TIME_Absolute last_started_at; | ||
170 | |||
171 | /** | ||
167 | * Absolute time at which the process is scheduled to restart in case of death | 172 | * Absolute time at which the process is scheduled to restart in case of death |
168 | */ | 173 | */ |
169 | struct GNUNET_TIME_Absolute restart_at; | 174 | struct GNUNET_TIME_Absolute restart_at; |
@@ -186,6 +191,11 @@ struct ServiceList { | |||
186 | * are on Windoze). | 191 | * are on Windoze). |
187 | */ | 192 | */ |
188 | int pipe_control; | 193 | int pipe_control; |
194 | |||
195 | /** | ||
196 | * Last exit status of the process. | ||
197 | */ | ||
198 | int last_exit_status; | ||
189 | }; | 199 | }; |
190 | 200 | ||
191 | /** | 201 | /** |
@@ -696,7 +706,7 @@ signal_result(struct GNUNET_SERVICE_Client *client, | |||
696 | */ | 706 | */ |
697 | static void | 707 | static void |
698 | broadcast_status(const char *name, | 708 | broadcast_status(const char *name, |
699 | enum GNUNET_ARM_ServiceStatus status, | 709 | enum GNUNET_ARM_ServiceMonitorStatus status, |
700 | struct GNUNET_SERVICE_Client *unicast) | 710 | struct GNUNET_SERVICE_Client *unicast) |
701 | { | 711 | { |
702 | struct GNUNET_MQ_Envelope *env; | 712 | struct GNUNET_MQ_Envelope *env; |
@@ -914,6 +924,7 @@ start_process(struct ServiceList *sl, | |||
914 | } | 924 | } |
915 | GNUNET_free(binary); | 925 | GNUNET_free(binary); |
916 | GNUNET_free(quotedbinary); | 926 | GNUNET_free(quotedbinary); |
927 | sl->last_started_at = GNUNET_TIME_absolute_get (); | ||
917 | if (NULL == sl->proc) | 928 | if (NULL == sl->proc) |
918 | { | 929 | { |
919 | GNUNET_log(GNUNET_ERROR_TYPE_ERROR, | 930 | GNUNET_log(GNUNET_ERROR_TYPE_ERROR, |
@@ -1300,6 +1311,29 @@ handle_stop(void *cls, const struct GNUNET_ARM_Message *amsg) | |||
1300 | 1311 | ||
1301 | 1312 | ||
1302 | /** | 1313 | /** |
1314 | * Write a string to a string pool. | ||
1315 | * | ||
1316 | * @param pool_start pointer to the start of the string pool | ||
1317 | * @param pool_size size of the string pool | ||
1318 | * @param[in,out] pool_pos current position index in the string pool, | ||
1319 | * will be updated | ||
1320 | * @param str string to write to the string pool | ||
1321 | * @returns GNUNET_OK if the string fits into the pool, | ||
1322 | * GNUNET_SYSERR otherwise | ||
1323 | */ | ||
1324 | static int | ||
1325 | pool_write(char *pool_start, size_t pool_size, size_t *pool_pos, char *str) | ||
1326 | { | ||
1327 | size_t next_pos = (*pool_pos) + strlen (str) + 1; | ||
1328 | |||
1329 | if (next_pos > pool_size) | ||
1330 | return GNUNET_SYSERR; | ||
1331 | memcpy (pool_start + *pool_pos, str, strlen (str) + 1); | ||
1332 | *pool_pos = next_pos; | ||
1333 | return GNUNET_OK; | ||
1334 | } | ||
1335 | |||
1336 | /** | ||
1303 | * Handle LIST-message. | 1337 | * Handle LIST-message. |
1304 | * | 1338 | * |
1305 | * @param cls identification of the client | 1339 | * @param cls identification of the client |
@@ -1311,42 +1345,68 @@ handle_list(void *cls, const struct GNUNET_ARM_Message *request) | |||
1311 | struct GNUNET_SERVICE_Client *client = cls; | 1345 | struct GNUNET_SERVICE_Client *client = cls; |
1312 | struct GNUNET_MQ_Envelope *env; | 1346 | struct GNUNET_MQ_Envelope *env; |
1313 | struct GNUNET_ARM_ListResultMessage *msg; | 1347 | struct GNUNET_ARM_ListResultMessage *msg; |
1314 | size_t string_list_size; | 1348 | size_t extra_size; |
1315 | struct ServiceList *sl; | 1349 | struct ServiceList *sl; |
1316 | uint16_t count; | 1350 | uint16_t count; |
1317 | char *pos; | 1351 | size_t pool_size; |
1352 | size_t pool_pos; | ||
1353 | char *pool_start; | ||
1354 | struct GNUNET_ARM_ServiceInfoMessage *ssm; | ||
1318 | 1355 | ||
1319 | GNUNET_break(0 == ntohl(request->reserved)); | 1356 | GNUNET_break_op(0 == ntohl(request->reserved)); |
1320 | count = 0; | 1357 | count = 0; |
1321 | string_list_size = 0; | 1358 | pool_size = 0; |
1322 | 1359 | ||
1323 | /* first count the running processes get their name's size */ | 1360 | /* Do one pass over the list to compute the number of services |
1361 | * and the string pool size */ | ||
1324 | for (sl = running_head; NULL != sl; sl = sl->next) | 1362 | for (sl = running_head; NULL != sl; sl = sl->next) |
1325 | { | 1363 | { |
1326 | if (NULL != sl->proc) | 1364 | pool_size += strlen(sl->name) + 1; |
1327 | { | 1365 | pool_size += strlen(sl->binary) + 1; |
1328 | string_list_size += strlen(sl->name); | 1366 | count++; |
1329 | string_list_size += strlen(sl->binary); | ||
1330 | string_list_size += 4; | ||
1331 | count++; | ||
1332 | } | ||
1333 | } | 1367 | } |
1334 | 1368 | ||
1369 | extra_size = pool_size + (count * sizeof (struct GNUNET_ARM_ServiceInfoMessage)); | ||
1335 | env = GNUNET_MQ_msg_extra(msg, | 1370 | env = GNUNET_MQ_msg_extra(msg, |
1336 | string_list_size, | 1371 | extra_size, |
1337 | GNUNET_MESSAGE_TYPE_ARM_LIST_RESULT); | 1372 | GNUNET_MESSAGE_TYPE_ARM_LIST_RESULT); |
1338 | msg->arm_msg.request_id = request->request_id; | 1373 | msg->arm_msg.request_id = request->request_id; |
1339 | msg->count = htons(count); | 1374 | msg->count = htons(count); |
1340 | 1375 | ||
1341 | pos = (char *)&msg[1]; | 1376 | ssm = (struct GNUNET_ARM_ServiceInfoMessage *) &msg[1]; |
1377 | pool_start = (char *) (ssm + count); | ||
1378 | pool_pos = 0; | ||
1379 | |||
1342 | for (sl = running_head; NULL != sl; sl = sl->next) | 1380 | for (sl = running_head; NULL != sl; sl = sl->next) |
1343 | { | 1381 | { |
1344 | if (NULL != sl->proc) | 1382 | ssm->name_index = htons ((uint16_t) pool_pos); |
1383 | GNUNET_assert (GNUNET_OK == pool_write (pool_start, pool_size, &pool_pos, sl->name)); | ||
1384 | ssm->binary_index = htons ((uint16_t) pool_pos); | ||
1385 | GNUNET_assert (GNUNET_OK == pool_write (pool_start, pool_size, &pool_pos, sl->binary)); | ||
1386 | if (NULL == sl->proc) | ||
1387 | { | ||
1388 | if (0 == sl->last_started_at.abs_value_us) | ||
1389 | { | ||
1390 | /* Process never started */ | ||
1391 | ssm->status = htonl (GNUNET_ARM_SERVICE_STATUS_STOPPED); | ||
1392 | } | ||
1393 | else if (0 == sl->last_exit_status) | ||
1345 | { | 1394 | { |
1346 | size_t s = strlen(sl->name) + strlen(sl->binary) + 4; | 1395 | ssm->status = htonl (GNUNET_ARM_SERVICE_STATUS_FINISHED); |
1347 | GNUNET_snprintf(pos, s, "%s (%s)", sl->name, sl->binary); | ||
1348 | pos += s; | ||
1349 | } | 1396 | } |
1397 | else | ||
1398 | { | ||
1399 | ssm->status = htonl (GNUNET_ARM_SERVICE_STATUS_FAILED); | ||
1400 | ssm->last_exit_status = htons (sl->last_exit_status); | ||
1401 | } | ||
1402 | } | ||
1403 | else | ||
1404 | { | ||
1405 | ssm->status = htonl (GNUNET_ARM_SERVICE_STATUS_STARTED); | ||
1406 | } | ||
1407 | ssm->last_started_at = GNUNET_TIME_absolute_hton (sl->last_started_at); | ||
1408 | ssm->restart_at = GNUNET_TIME_absolute_hton (sl->restart_at); | ||
1409 | ssm++; | ||
1350 | } | 1410 | } |
1351 | GNUNET_MQ_send(GNUNET_SERVICE_client_get_mq(client), env); | 1411 | GNUNET_MQ_send(GNUNET_SERVICE_client_get_mq(client), env); |
1352 | GNUNET_SERVICE_client_continue(client); | 1412 | GNUNET_SERVICE_client_continue(client); |
@@ -1700,6 +1760,7 @@ maint_child_death(void *cls) | |||
1700 | } | 1760 | } |
1701 | if (GNUNET_YES != in_shutdown) | 1761 | if (GNUNET_YES != in_shutdown) |
1702 | { | 1762 | { |
1763 | pos->last_exit_status = statcode; | ||
1703 | if ((statusType == GNUNET_OS_PROCESS_EXITED) && (statcode == 0)) | 1764 | if ((statusType == GNUNET_OS_PROCESS_EXITED) && (statcode == 0)) |
1704 | { | 1765 | { |
1705 | /* process terminated normally, allow restart at any time */ | 1766 | /* process terminated normally, allow restart at any time */ |
@@ -1722,7 +1783,7 @@ maint_child_death(void *cls) | |||
1722 | else | 1783 | else |
1723 | { | 1784 | { |
1724 | GNUNET_log( | 1785 | GNUNET_log( |
1725 | GNUNET_ERROR_TYPE_INFO, | 1786 | GNUNET_ERROR_TYPE_WARNING, |
1726 | _("Service `%s' terminated with status %s/%d, will restart in %s\n"), | 1787 | _("Service `%s' terminated with status %s/%d, will restart in %s\n"), |
1727 | pos->name, | 1788 | pos->name, |
1728 | statstr, | 1789 | statstr, |