From: Christian Grothoff Date: Tue, 4 May 2010 11:14:25 +0000 (+0000) Subject: calling sync, cleaning up files X-Git-Tag: initial-import-from-subversion-38251~21900 X-Git-Url: https://git.librecmc.org/?a=commitdiff_plain;h=6276a671135e01b119f198d0ae3092bfeb14903e;p=oweals%2Fgnunet.git calling sync, cleaning up files --- diff --git a/TODO b/TODO index 14f1d5ce6..3637418cb 100644 --- a/TODO +++ b/TODO @@ -1,10 +1,8 @@ 0.9.0pre1: * FS: [CG] - - actually call 'sync' functions (publish, unindex, search, download) - code review: => refactor fs.c to join common code segments! => document directory structure (and use #define's for the directory names!) - => ensure all files & dirs are cleaned up! (at least during 'clean' runs) - persistence testing (publish, unindex, search, download): => need driver! => schedule suspending tasks DURING event handler => good coverage! diff --git a/src/fs/fs.c b/src/fs/fs.c index 371568ddf..ba899d6d4 100644 --- a/src/fs/fs.c +++ b/src/fs/fs.c @@ -422,10 +422,11 @@ get_serialization_file_name (struct GNUNET_FS_Handle *h, &basename)) return NULL; GNUNET_asprintf (&ret, - "%s%s%s-%s%s%s", + "%s%s%s%s%s%s", basename, DIR_SEPARATOR_STR, h->client_name, + DIR_SEPARATOR_STR, ext, DIR_SEPARATOR_STR, ent); @@ -513,6 +514,40 @@ GNUNET_FS_remove_sync_file_ (struct GNUNET_FS_Handle *h, } +/** + * Remove serialization/deserialization directory from disk. + * + * @param h master context + * @param ext component of the path + * @param uni unique name of parent + */ +void +GNUNET_FS_remove_sync_dir_ (struct GNUNET_FS_Handle *h, + const char *ext, + const char *uni) +{ + char *dn; + char pbuf[32]; + + if (uni == NULL) + return; + GNUNET_snprintf (pbuf, + sizeof (pbuf), + "%s%s%s", + ext, + DIR_SEPARATOR_STR, + uni); + dn = get_serialization_file_name (h, ext, ""); + if (dn == NULL) + return; + if (GNUNET_OK != GNUNET_DISK_directory_remove (dn)) + GNUNET_log_strerror_file (GNUNET_ERROR_TYPE_WARNING, + "rmdir", + dn); + GNUNET_free (dn); +} + + /** * Serialize a 'start_time'. Since we use start-times to * calculate the duration of some operation, we actually @@ -1397,7 +1432,6 @@ void GNUNET_FS_download_sync_ (struct GNUNET_FS_DownloadContext *dc) { struct GNUNET_BIO_WriteHandle *wh; - struct DownloadRequest *dr; char pbuf[32]; const char *category; char *uris; @@ -1437,17 +1471,9 @@ GNUNET_FS_download_sync_ (struct GNUNET_FS_DownloadContext *dc) uris = GNUNET_FS_uri_to_string (dc->uri); num_pending = 0; if (dc->emsg != NULL) - { - dr = dc->pending; - while (dr != NULL) - { - num_pending++; - dr = dr->next; - } - (void) GNUNET_CONTAINER_multihashmap_iterate (dc->active, - &count_download_requests, - &num_pending); - } + (void) GNUNET_CONTAINER_multihashmap_iterate (dc->active, + &count_download_requests, + &num_pending); GNUNET_assert ( (dc->length == dc->completed) || (dc->emsg != NULL) || (num_pending > 0) ); @@ -1480,28 +1506,11 @@ GNUNET_FS_download_sync_ (struct GNUNET_FS_DownloadContext *dc) (GNUNET_OK != GNUNET_BIO_write_int32 (wh, num_pending)) ) goto cleanup; - dr = dc->pending; - while (dr != NULL) - { - if (GNUNET_YES != - write_download_request (wh, NULL, dr)) - goto cleanup; - dr = dr->next; - } if (GNUNET_SYSERR == GNUNET_CONTAINER_multihashmap_iterate (dc->active, &write_download_request, wh)) goto cleanup; - while (0 < num_pending--) - { - dr = GNUNET_malloc (sizeof (struct DownloadRequest)); - - dr->is_pending = GNUNET_YES; - dr->next = dc->pending; - dc->pending = dr; - dr = NULL; - } GNUNET_free_non_null (uris); if (GNUNET_OK == GNUNET_BIO_write_close (wh)) @@ -1524,18 +1533,14 @@ GNUNET_FS_download_sync_ (struct GNUNET_FS_DownloadContext *dc) * publishing structs should already call "sync" internally, * so this function is likely not useful for clients. * - * @param key key for the search result * @param sr the struct to sync */ void -GNUNET_FS_search_result_sync_ (const GNUNET_HashCode *key, - struct GNUNET_FS_SearchResult *sr) +GNUNET_FS_search_result_sync_ (struct GNUNET_FS_SearchResult *sr) { struct GNUNET_BIO_WriteHandle *wh; char *uris; - GNUNET_assert ( (GNUNET_YES == GNUNET_FS_uri_test_chk (sr->uri)) || - (GNUNET_YES == GNUNET_FS_uri_test_loc (sr->uri)) ); uris = NULL; if (NULL == sr->serialization) sr->serialization = make_serialization_file_name (sr->sc->h, @@ -1551,7 +1556,7 @@ GNUNET_FS_search_result_sync_ (const GNUNET_HashCode *key, (GNUNET_OK != GNUNET_BIO_write_meta_data (wh, sr->meta)) || (GNUNET_OK != - GNUNET_BIO_write (wh, key, sizeof (GNUNET_HashCode))) || + GNUNET_BIO_write (wh, &sr->key, sizeof (GNUNET_HashCode))) || (GNUNET_OK != GNUNET_BIO_write_int32 (wh, sr->mandatory_missing)) || (GNUNET_OK != @@ -1844,7 +1849,6 @@ deserialize_search_result (void *cls, struct GNUNET_BIO_ReadHandle *rh; struct GNUNET_BIO_ReadHandle *drh; struct GNUNET_FS_SearchResult *sr; - GNUNET_HashCode key; ser = get_serialization_short_name (filename); rh = GNUNET_BIO_read_open (filename); @@ -1871,14 +1875,12 @@ deserialize_search_result (void *cls, if ( (GNUNET_OK != GNUNET_BIO_read_string (rh, "result-uri", &uris, 10*1024)) || (NULL == (sr->uri = GNUNET_FS_uri_parse (uris, &emsg))) || - ( (GNUNET_YES != GNUNET_FS_uri_test_chk (sr->uri)) && - (GNUNET_YES != GNUNET_FS_uri_test_loc (sr->uri)) ) || (GNUNET_OK != GNUNET_BIO_read_string (rh, "download-lnk", &download, 16)) || (GNUNET_OK != GNUNET_BIO_read_meta_data (rh, "result-meta", &sr->meta)) || (GNUNET_OK != - GNUNET_BIO_read (rh, "result-key", &key, sizeof (key))) || + GNUNET_BIO_read (rh, "result-key", &sr->key, sizeof (GNUNET_HashCode))) || (GNUNET_OK != GNUNET_BIO_read_int32 (rh, &sr->mandatory_missing)) || (GNUNET_OK != @@ -1911,7 +1913,7 @@ deserialize_search_result (void *cls, GNUNET_free (download); } GNUNET_CONTAINER_multihashmap_put (sc->master_result_map, - &key, + &sr->key, sr, GNUNET_CONTAINER_MULTIHASHMAPOPTION_MULTIPLE); return GNUNET_OK; @@ -2476,9 +2478,12 @@ deserialize_download_file (void *cls, rh = GNUNET_BIO_read_open (filename); if (rh == NULL) { - if (ser != NULL) + if (filename != NULL) { - GNUNET_FS_remove_sync_file_ (h, "download", ser); + if (0 != UNLINK (filename)) + GNUNET_log_strerror_file (GNUNET_ERROR_TYPE_WARNING, + "unlink", + filename); GNUNET_free (ser); } return GNUNET_OK; diff --git a/src/fs/fs.h b/src/fs/fs.h index 1d3498a7c..52fbee4c1 100644 --- a/src/fs/fs.h +++ b/src/fs/fs.h @@ -620,6 +620,11 @@ struct GNUNET_FS_SearchResult */ char *serialization; + /** + * Key for the search result + */ + GNUNET_HashCode key; + /** * ID of the task that will clean up the probe_ctx should it not * complete on time (and that will need to be cancelled if we clean @@ -894,6 +899,19 @@ GNUNET_FS_remove_sync_file_ (struct GNUNET_FS_Handle *h, const char *ent); +/** + * Remove serialization/deserialization directory from disk. + * + * @param h master context + * @param ext component of the path + * @param uni unique name of parent + */ +void +GNUNET_FS_remove_sync_dir_ (struct GNUNET_FS_Handle *h, + const char *ext, + const char *uni); + + /** * Synchronize this file-information struct with its mirror * on disk. Note that all internal FS-operations that change @@ -944,12 +962,10 @@ GNUNET_FS_search_sync_ (struct GNUNET_FS_SearchContext *sc); * publishing structs should already call "sync" internally, * so this function is likely not useful for clients. * - * @param key key for the search result * @param sr the struct to sync */ void -GNUNET_FS_search_result_sync_ (const GNUNET_HashCode *key, - struct GNUNET_FS_SearchResult *sr); +GNUNET_FS_search_result_sync_ (struct GNUNET_FS_SearchResult *sr); /** * Synchronize this download struct with its mirror diff --git a/src/fs/fs_download.c b/src/fs/fs_download.c index 2fd8e0412..8d5a936f0 100644 --- a/src/fs/fs_download.c +++ b/src/fs/fs_download.c @@ -23,7 +23,6 @@ * @author Christian Grothoff * * TODO: - * - persistence (can wait) * - location URI suppport (can wait, easy) * - different priority for scheduling probe downloads? * - check if iblocks can be computed from existing blocks (can wait, hard) @@ -640,6 +639,7 @@ check_completed (struct GNUNET_FS_DownloadContext *dc) pos = pos->next; } dc->has_finished = GNUNET_YES; + GNUNET_FS_download_sync_ (dc); /* signal completion */ pi.status = GNUNET_FS_STATUS_DOWNLOAD_COMPLETED; GNUNET_FS_download_make_status_ (&pi, dc); @@ -1032,9 +1032,9 @@ process_result_with_request (void *cls, } GNUNET_assert (sm->depth == dc->treedepth); } - // FIXME: make persistent if (sm->depth == dc->treedepth) { + GNUNET_FS_download_sync_ (dc); GNUNET_free (sm); return GNUNET_YES; } @@ -1060,6 +1060,7 @@ process_result_with_request (void *cls, sm->depth + 1); } GNUNET_free (sm); + GNUNET_FS_download_sync_ (dc); return GNUNET_YES; signal_error: @@ -1075,8 +1076,10 @@ process_result_with_request (void *cls, dc->th = NULL; } GNUNET_CLIENT_disconnect (dc->client, GNUNET_NO); + /* FIXME: clean up dc->active / pending! */ dc->client = NULL; GNUNET_free (sm); + GNUNET_FS_download_sync_ (dc); return GNUNET_NO; } @@ -1553,7 +1556,6 @@ GNUNET_FS_download_start (struct GNUNET_FS_Handle *h, "Download tree has depth %u\n", dc->treedepth); #endif - // FIXME: make persistent pi.status = GNUNET_FS_STATUS_DOWNLOAD_START; pi.value.download.specifics.start.meta = meta; GNUNET_FS_download_make_status_ (&pi, dc); @@ -1561,6 +1563,7 @@ GNUNET_FS_download_start (struct GNUNET_FS_Handle *h, &dc->uri->data.chk.chk, 0, 1 /* 0 == CHK, 1 == top */); + GNUNET_FS_download_sync_ (dc); GNUNET_FS_download_start_downloading_ (dc); if (parent == NULL) dc->top = GNUNET_FS_make_top (dc->h, @@ -1682,7 +1685,6 @@ GNUNET_FS_download_start_from_search (struct GNUNET_FS_Handle *h, "Download tree has depth %u\n", dc->treedepth); #endif - // FIXME: make persistent pi.status = GNUNET_FS_STATUS_DOWNLOAD_START; pi.value.download.specifics.start.meta = dc->meta; GNUNET_FS_download_make_status_ (&pi, dc); @@ -1690,6 +1692,7 @@ GNUNET_FS_download_start_from_search (struct GNUNET_FS_Handle *h, &dc->uri->data.chk.chk, 0, 1 /* 0 == CHK, 1 == top */); + GNUNET_FS_download_sync_ (dc); GNUNET_FS_download_start_downloading_ (dc); return dc; } @@ -1722,6 +1725,7 @@ GNUNET_FS_download_stop (struct GNUNET_FS_DownloadContext *dc, int do_delete) { struct GNUNET_FS_ProgressInfo pi; + int have_children; if (dc->top != NULL) GNUNET_FS_end_top (dc->h, dc->top); @@ -1735,15 +1739,24 @@ GNUNET_FS_download_stop (struct GNUNET_FS_DownloadContext *dc, GNUNET_FS_dequeue_ (dc->job_queue); dc->job_queue = NULL; } + have_children = (NULL != dc->child_head) ? GNUNET_YES : GNUNET_NO; while (NULL != dc->child_head) GNUNET_FS_download_stop (dc->child_head, do_delete); - // FIXME: make unpersistent if (dc->parent != NULL) GNUNET_CONTAINER_DLL_remove (dc->parent->child_head, dc->parent->child_tail, - dc); - + dc); + if (dc->serialization != NULL) + GNUNET_FS_remove_sync_file_ (dc->h, + (dc->parent != NULL) + ? "subdownloads" + : "download", + dc->serialization); + if (GNUNET_YES == have_children) + GNUNET_FS_remove_sync_dir_ (dc->h, + "subdownloads", + dc->serialization); pi.status = GNUNET_FS_STATUS_DOWNLOAD_STOPPED; GNUNET_FS_download_make_status_ (&pi, dc); if (GNUNET_SCHEDULER_NO_TASK != dc->task) @@ -1775,7 +1788,6 @@ GNUNET_FS_download_stop (struct GNUNET_FS_DownloadContext *dc, dc->temp_filename); GNUNET_free (dc->temp_filename); } - /* FIXME: clean up serialization file itself! */ GNUNET_free_non_null (dc->serialization); GNUNET_free (dc); } diff --git a/src/fs/fs_publish.c b/src/fs/fs_publish.c index 0c4ebba7b..8d2dacb14 100644 --- a/src/fs/fs_publish.c +++ b/src/fs/fs_publish.c @@ -21,13 +21,12 @@ /** * @file fs/fs_publish.c * @brief publish a file or directory in GNUnet - * @see http://gnunet.org/encoding.php3 + * @see http://gnunet.org/encoding * @author Krista Bennett * @author Christian Grothoff * * TODO: * - indexing cleanup: unindex on failure (can wait) - * - persistence support (can wait) * - datastore reservation support (optimization) * - location URIs (publish with anonymity-level zero) */ @@ -191,7 +190,7 @@ signal_publish_completion (struct GNUNET_FS_FileInformation *p, pi.value.publish.eta = GNUNET_TIME_UNIT_ZERO; pi.value.publish.specifics.completed.chk_uri = p->chk_uri; p->client_info = GNUNET_FS_publish_make_status_ (&pi, sc, p, - GNUNET_ntohll (p->chk_uri->data.chk.file_length)); + GNUNET_ntohll (p->chk_uri->data.chk.file_length)); } @@ -232,17 +231,19 @@ publish_sblocks_cont (void *cls, const struct GNUNET_FS_Uri *uri, const char *emsg) { - struct GNUNET_FS_PublishContext *sc = cls; + struct GNUNET_FS_PublishContext *pc = cls; if (NULL != emsg) { - signal_publish_error (sc->fi, - sc, + signal_publish_error (pc->fi, + pc, emsg); + GNUNET_FS_publish_sync_ (pc); return; } // FIXME: release the datastore reserve here! - signal_publish_completion (sc->fi, sc); - sc->all_done = GNUNET_YES; + signal_publish_completion (pc->fi, pc); + pc->all_done = GNUNET_YES; + GNUNET_FS_publish_sync_ (pc); } @@ -287,31 +288,34 @@ publish_kblocks_cont (void *cls, const struct GNUNET_FS_Uri *uri, const char *emsg) { - struct GNUNET_FS_PublishContext *sc = cls; - struct GNUNET_FS_FileInformation *p = sc->fi_pos; + struct GNUNET_FS_PublishContext *pc = cls; + struct GNUNET_FS_FileInformation *p = pc->fi_pos; if (NULL != emsg) { - signal_publish_error (p, sc, emsg); - sc->upload_task - = GNUNET_SCHEDULER_add_with_priority (sc->h->sched, + signal_publish_error (p, pc, emsg); + GNUNET_FS_file_information_sync_ (p); + GNUNET_FS_publish_sync_ (pc); + pc->upload_task + = GNUNET_SCHEDULER_add_with_priority (pc->h->sched, GNUNET_SCHEDULER_PRIORITY_BACKGROUND, &GNUNET_FS_publish_main_, - sc); + pc); return; } if (NULL != p->dir) - signal_publish_completion (p, sc); + signal_publish_completion (p, pc); /* move on to next file */ if (NULL != p->next) - sc->fi_pos = p->next; + pc->fi_pos = p->next; else - sc->fi_pos = p->dir; - sc->upload_task - = GNUNET_SCHEDULER_add_with_priority (sc->h->sched, + pc->fi_pos = p->dir; + GNUNET_FS_publish_sync_ (pc); + pc->upload_task + = GNUNET_SCHEDULER_add_with_priority (pc->h->sched, GNUNET_SCHEDULER_PRIORITY_BACKGROUND, &GNUNET_FS_publish_main_, - sc); + pc); } @@ -597,6 +601,7 @@ publish_content (struct GNUNET_FS_PublishContext *sc) GNUNET_FS_directory_builder_finish (db, &p->data.dir.dir_size, &p->data.dir.dir_data); + GNUNET_FS_file_information_sync_ (p); } size = (p->is_directory) ? p->data.dir.dir_size @@ -640,6 +645,7 @@ process_index_start_response (void *cls, p->filename, _("timeout on index-start request to `fs' service")); p->data.file.do_index = GNUNET_NO; + GNUNET_FS_file_information_sync_ (p); publish_content (sc); return; } @@ -655,11 +661,13 @@ process_index_start_response (void *cls, p->filename, gettext (emsg)); p->data.file.do_index = GNUNET_NO; + GNUNET_FS_file_information_sync_ (p); publish_content (sc); return; } p->data.file.index_start_confirmed = GNUNET_YES; /* success! continue with indexing */ + GNUNET_FS_file_information_sync_ (p); publish_content (sc); } @@ -693,6 +701,7 @@ hash_for_index_cb (void *cls, p->filename, _("failed to compute hash")); p->data.file.do_index = GNUNET_NO; + GNUNET_FS_file_information_sync_ (p); publish_content (sc); return; } @@ -711,6 +720,7 @@ hash_for_index_cb (void *cls, _("filename too long")); GNUNET_free (fn); p->data.file.do_index = GNUNET_NO; + GNUNET_FS_file_information_sync_ (p); publish_content (sc); return; } @@ -734,8 +744,12 @@ hash_for_index_cb (void *cls, GNUNET_free (fn); return; } - p->data.file.file_id = *res; - p->data.file.have_hash = GNUNET_YES; + if (p->data.file.have_hash != GNUNET_YES) + { + p->data.file.file_id = *res; + p->data.file.have_hash = GNUNET_YES; + GNUNET_FS_file_information_sync_ (p); + } ism = GNUNET_malloc (sizeof(struct IndexStartMessage) + slen); ism->header.size = htons(sizeof(struct IndexStartMessage) + @@ -793,6 +807,7 @@ GNUNET_FS_publish_main_ (void *cls, { /* upload of entire hierarchy complete, publish namespace entries */ + GNUNET_FS_publish_sync_ (sc); publish_sblock (sc); return; } @@ -804,6 +819,7 @@ GNUNET_FS_publish_main_ (void *cls, { p = p->data.dir.entries; sc->fi_pos = p; + GNUNET_FS_publish_sync_ (sc); } /* abort on error */ if (NULL != p->emsg) @@ -835,11 +851,13 @@ GNUNET_FS_publish_main_ (void *cls, p->client_info = GNUNET_FS_publish_make_status_ (&pi, sc, p, 0); } sc->all_done = GNUNET_YES; + GNUNET_FS_publish_sync_ (sc); return; } /* handle completion */ if (NULL != p->chk_uri) { + GNUNET_FS_publish_sync_ (sc); /* upload of "p" complete, publish KBlocks! */ if (p->keywords != NULL) { @@ -872,12 +890,15 @@ GNUNET_FS_publish_main_ (void *cls, _("Can not index file `%s': %s. Will try to insert instead.\n"), "", _("needs to be an actual file")); + GNUNET_FS_file_information_sync_ (p); publish_content (sc); return; } if (p->data.file.have_hash) - hash_for_index_cb (sc, - &p->data.file.file_id); + { + hash_for_index_cb (sc, + &p->data.file.file_id); + } else { p->start_time = GNUNET_TIME_absolute_get (); @@ -925,6 +946,7 @@ fip_signal_start(void *cls, pi.status = GNUNET_FS_STATUS_PUBLISH_START; *client_info = GNUNET_FS_publish_make_status_ (&pi, sc, fi, 0); + GNUNET_FS_file_information_sync_ (fi); return GNUNET_OK; } @@ -962,7 +984,7 @@ fip_signal_suspend(void *cls, GNUNET_free_non_null (fi->serialization); fi->serialization = NULL; off = (fi->chk_uri == NULL) ? 0 : length; - pi.status = GNUNET_FS_STATUS_PUBLISH_STOPPED; + pi.status = GNUNET_FS_STATUS_PUBLISH_SUSPEND; GNUNET_break (NULL == GNUNET_FS_publish_make_status_ (&pi, sc, fi, off)); *client_info = NULL; return GNUNET_OK; diff --git a/src/fs/fs_search.c b/src/fs/fs_search.c index 36aa26193..8db9f115d 100644 --- a/src/fs/fs_search.c +++ b/src/fs/fs_search.c @@ -24,7 +24,6 @@ * @author Christian Grothoff * * TODO: - * - insert code for serialization where needed * - remove *directory* with search results upon completion * - centralize code that sprintf's the 'pbuf[32]' strings * - add support for pushing "already seen" information @@ -52,7 +51,8 @@ void * GNUNET_FS_search_make_status_ (struct GNUNET_FS_ProgressInfo *pi, struct GNUNET_FS_SearchContext *sc) -{ +{ + void *ret; pi->value.search.sc = sc; pi->value.search.cctx = sc->client_info; @@ -62,8 +62,9 @@ GNUNET_FS_search_make_status_ (struct GNUNET_FS_ProgressInfo *pi, = sc->uri; pi->value.search.duration = GNUNET_TIME_absolute_get_duration (sc->start_time); pi->value.search.anonymity = sc->anonymity; - return sc->h->upcb (sc->h->upcb_cls, + ret = sc->h->upcb (sc->h->upcb_cls, pi); + return ret; } @@ -217,6 +218,7 @@ probe_failure_handler (void *cls, { struct GNUNET_FS_SearchResult *sr = cls; sr->availability_trials++; + GNUNET_FS_search_result_sync_ (sr); signal_probe_result (sr); } @@ -234,6 +236,7 @@ probe_success_handler (void *cls, struct GNUNET_FS_SearchResult *sr = cls; sr->availability_trials++; sr->availability_success++; + GNUNET_FS_search_result_sync_ (sr); signal_probe_result (sr); } @@ -327,6 +330,7 @@ GNUNET_FS_search_probe_progress_ (void *cls, dur = GNUNET_TIME_absolute_get_duration (sr->probe_active_time); sr->remaining_probe_time = GNUNET_TIME_relative_subtract (sr->remaining_probe_time, dur); + GNUNET_FS_search_result_sync_ (sr); break; default: GNUNET_break (0); @@ -427,6 +431,7 @@ process_ksk_result (struct GNUNET_FS_SearchContext *sc, sr->uri = GNUNET_FS_uri_dup (uri); sr->meta = GNUNET_CONTAINER_meta_data_duplicate (meta); sr->mandatory_missing = sc->mandatory_count; + sr->key = key; GNUNET_CONTAINER_multihashmap_put (sc->master_result_map, &key, sr, @@ -447,6 +452,7 @@ process_ksk_result (struct GNUNET_FS_SearchContext *sc, notify_client_chk_result (sc, sr); else notify_client_chk_update (sc, sr); + GNUNET_FS_search_result_sync_ (sr); GNUNET_FS_search_start_probe_ (sr); } @@ -506,10 +512,12 @@ process_sks_result (struct GNUNET_FS_SearchContext *sc, sr->sc = sc; sr->uri = GNUNET_FS_uri_dup (uri); sr->meta = GNUNET_CONTAINER_meta_data_duplicate (meta); + sr->key = key; GNUNET_CONTAINER_multihashmap_put (sc->master_result_map, &key, sr, GNUNET_CONTAINER_MULTIHASHMAPOPTION_MULTIPLE); + GNUNET_FS_search_result_sync_ (sr); GNUNET_FS_search_start_probe_ (sr); /* notify client */ notify_client_chk_result (sc, sr); @@ -1090,6 +1098,7 @@ search_start (struct GNUNET_FS_Handle *h, GNUNET_free (sc); return NULL; } + GNUNET_FS_search_sync_ (sc); pi.status = GNUNET_FS_STATUS_SEARCH_START; sc->client_info = GNUNET_FS_search_make_status_ (&pi, sc); return sc; @@ -1299,7 +1308,7 @@ GNUNET_FS_search_pause (struct GNUNET_FS_SearchContext *sc) if (NULL != sc->client) GNUNET_CLIENT_disconnect (sc->client, GNUNET_NO); sc->client = NULL; - // FIXME: make persistent! + GNUNET_FS_search_sync_ (sc); // FIXME: should this freeze all active probes? pi.status = GNUNET_FS_STATUS_SEARCH_PAUSED; sc->client_info = GNUNET_FS_search_make_status_ (&pi, sc); @@ -1319,7 +1328,7 @@ GNUNET_FS_search_continue (struct GNUNET_FS_SearchContext *sc) GNUNET_assert (sc->client == NULL); GNUNET_assert (sc->task == GNUNET_SCHEDULER_NO_TASK); do_reconnect (sc, NULL); - // FIXME: make persistent! + GNUNET_FS_search_sync_ (sc); pi.status = GNUNET_FS_STATUS_SEARCH_CONTINUED; sc->client_info = GNUNET_FS_search_make_status_ (&pi, sc); } @@ -1395,10 +1404,14 @@ GNUNET_FS_search_stop (struct GNUNET_FS_SearchContext *sc) struct GNUNET_FS_ProgressInfo pi; unsigned int i; struct GNUNET_FS_SearchContext *parent; + int had_result; if (sc->top != NULL) GNUNET_FS_end_top (sc->h, sc->top); - // FIXME: make un-persistent! + if (sc->serialization != NULL) + GNUNET_FS_remove_sync_file_ (sc->h, + (sc->parent != NULL) ? "search-children" : "search", + sc->serialization); if (NULL != (parent = sc->parent)) { GNUNET_CONTAINER_DLL_remove (parent->child_head, @@ -1408,9 +1421,12 @@ GNUNET_FS_search_stop (struct GNUNET_FS_SearchContext *sc) } while (NULL != sc->child_head) GNUNET_FS_search_stop (sc->child_head); + had_result = (0 != GNUNET_CONTAINER_multihashmap_size (sc->master_result_map)) ? GNUNET_YES : GNUNET_NO; GNUNET_CONTAINER_multihashmap_iterate (sc->master_result_map, &search_result_free, sc); + if (had_result) + GNUNET_FS_remove_sync_dir_ (sc->h, "search-results", sc->serialization); pi.status = GNUNET_FS_STATUS_SEARCH_STOPPED; sc->client_info = GNUNET_FS_search_make_status_ (&pi, sc); GNUNET_break (NULL == sc->client_info); diff --git a/src/fs/fs_unindex.c b/src/fs/fs_unindex.c index c79b3413e..9d14bb0cb 100644 --- a/src/fs/fs_unindex.c +++ b/src/fs/fs_unindex.c @@ -142,14 +142,13 @@ unindex_progress (void *cls, * @param emsg the error message */ static void -signal_unindex_error (struct GNUNET_FS_UnindexContext *uc, - const char *emsg) +signal_unindex_error (struct GNUNET_FS_UnindexContext *uc) { struct GNUNET_FS_ProgressInfo pi; pi.status = GNUNET_FS_STATUS_UNINDEX_ERROR; pi.value.unindex.eta = GNUNET_TIME_UNIT_FOREVER_REL; - pi.value.unindex.specifics.error.message = emsg; + pi.value.unindex.specifics.error.message = uc->emsg; GNUNET_FS_unindex_make_status_ (&pi, uc, 0); } @@ -170,11 +169,10 @@ process_cont (void *cls, struct GNUNET_FS_UnindexContext *uc = cls; if (success == GNUNET_SYSERR) { - signal_unindex_error (uc, - msg); + uc->emsg = GNUNET_strdup (msg); + signal_unindex_error (uc); return; - } - + } GNUNET_FS_tree_encoder_next (uc->tc); } @@ -254,8 +252,8 @@ unindex_finish (void *cls, uc->dsh = NULL; if (emsg != NULL) { - signal_unindex_error (uc, emsg); - GNUNET_free (emsg); + uc->emsg = emsg; + signal_unindex_error (uc); } else { @@ -263,6 +261,7 @@ unindex_finish (void *cls, pi.value.unindex.eta = GNUNET_TIME_UNIT_ZERO; GNUNET_FS_unindex_make_status_ (&pi, uc, uc->file_size); } + GNUNET_FS_unindex_sync_ (uc); } @@ -292,18 +291,21 @@ process_fs_response (void *cls, if (NULL == msg) { uc->state = UNINDEX_STATE_ERROR; - signal_unindex_error (uc, - _("Timeout waiting for `fs' service.")); + uc->emsg = GNUNET_strdup (_("Timeout waiting for `fs' service.")); + GNUNET_FS_unindex_sync_ (uc); + signal_unindex_error (uc); return; } if (ntohs(msg->type) != GNUNET_MESSAGE_TYPE_FS_UNINDEX_OK) { uc->state = UNINDEX_STATE_ERROR; - signal_unindex_error (uc, - _("Invalid response from `fs' service.")); + uc->emsg = GNUNET_strdup (_("Invalid response from `fs' service.")); + GNUNET_FS_unindex_sync_ (uc); + signal_unindex_error (uc); return; } uc->state = UNINDEX_STATE_DS_REMOVE; + GNUNET_FS_unindex_sync_ (uc); GNUNET_FS_unindex_do_remove_ (uc); } @@ -321,8 +323,9 @@ GNUNET_FS_unindex_do_remove_ (struct GNUNET_FS_UnindexContext *uc) if (NULL == uc->dsh) { uc->state = UNINDEX_STATE_ERROR; - signal_unindex_error (uc, - _("Failed to connect to `datastore' service.")); + uc->emsg = GNUNET_strdup (_("Failed to connect to `datastore' service.")); + GNUNET_FS_unindex_sync_ (uc); + signal_unindex_error (uc); return; } uc->fh = GNUNET_DISK_file_open (uc->filename, @@ -333,8 +336,9 @@ GNUNET_FS_unindex_do_remove_ (struct GNUNET_FS_UnindexContext *uc) GNUNET_DATASTORE_disconnect (uc->dsh, GNUNET_NO); uc->dsh = NULL; uc->state = UNINDEX_STATE_ERROR; - signal_unindex_error (uc, - _("Failed to open file for unindexing.")); + uc->emsg = GNUNET_strdup (_("Failed to open file for unindexing.")); + GNUNET_FS_unindex_sync_ (uc); + signal_unindex_error (uc); return; } uc->tc = GNUNET_FS_tree_encoder_create (uc->h, @@ -370,12 +374,14 @@ GNUNET_FS_unindex_process_hash_ (void *cls, if (file_id == NULL) { uc->state = UNINDEX_STATE_ERROR; - signal_unindex_error (uc, - _("Failed to compute hash of file.")); + uc->emsg = GNUNET_strdup (_("Failed to compute hash of file.")); + GNUNET_FS_unindex_sync_ (uc); + signal_unindex_error (uc); return; } uc->file_id = *file_id; uc->state = UNINDEX_STATE_FS_NOTIFY; + GNUNET_FS_unindex_sync_ (uc); uc->client = GNUNET_CLIENT_connect (uc->h->sched, "fs", uc->h->cfg); @@ -445,8 +451,7 @@ GNUNET_FS_unindex_start (struct GNUNET_FS_Handle *h, ret->start_time = GNUNET_TIME_absolute_get (); ret->file_size = size; ret->client_info = cctx; - - // FIXME: make persistent! + GNUNET_FS_unindex_sync_ (ret); pi.status = GNUNET_FS_STATUS_UNINDEX_START; pi.value.unindex.eta = GNUNET_TIME_UNIT_FOREVER_REL; GNUNET_FS_unindex_make_status_ (&pi, ret, 0); diff --git a/src/fs/test_fs_download.c b/src/fs/test_fs_download.c index 047c314e4..068095269 100644 --- a/src/fs/test_fs_download.c +++ b/src/fs/test_fs_download.c @@ -193,6 +193,9 @@ progress_cb (void *cls, &abort_download_task, NULL); break; + case GNUNET_FS_STATUS_DOWNLOAD_ACTIVE: + case GNUNET_FS_STATUS_DOWNLOAD_INACTIVE: + break; case GNUNET_FS_STATUS_PUBLISH_START: GNUNET_assert (0 == strcmp ("publish-context", event->value.publish.cctx)); GNUNET_assert (NULL == event->value.publish.pctx); diff --git a/src/util/disk.c b/src/util/disk.c index 4477dc135..e3a58531b 100644 --- a/src/util/disk.c +++ b/src/util/disk.c @@ -1202,7 +1202,6 @@ GNUNET_DISK_file_open (const char *fn, expfn = GNUNET_STRINGS_filename_expand (fn); if (NULL == expfn) return NULL; - #ifndef MINGW mode = 0; if (GNUNET_DISK_OPEN_READWRITE == (flags & GNUNET_DISK_OPEN_READWRITE)) @@ -1225,6 +1224,7 @@ GNUNET_DISK_file_open (const char *fn, oflags |= O_APPEND; if (flags & GNUNET_DISK_OPEN_CREATE) { + (void) GNUNET_DISK_directory_create_for_file (expfn); oflags |= O_CREAT; if (perm & GNUNET_DISK_PERM_USER_READ) mode |= S_IRUSR;