summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorNick Mathewson <nickm@torproject.org>2013-06-12 12:04:33 -0400
committerNick Mathewson <nickm@torproject.org>2013-06-12 12:04:33 -0400
commitf455686b77e4ac686251c6edf1f4a506a369866c (patch)
tree72f904cc2464b984cc4c872c8e079abfa359bdf7
parentfff9386af87bd0f54cda1ef4fe0bf131de7c3d8e (diff)
downloadtor-f455686b77e4ac686251c6edf1f4a506a369866c.tar.gz
tor-f455686b77e4ac686251c6edf1f4a506a369866c.zip
Unmap the microdescriptor cache before replacing it.
This is a reprise of the fix in bdff7e3299d78; 6905c1f6 reintroduced that bug. Briefly: windows doesn't seem to like deleting a mapped file. I tried adding the PROT_SHARED_DELETE flag to the createfile all, but that didn't actually fix this issue. Fortunately, the unit test I added in 4f4fc63fea0589a4fa03f3859dc27860cdde75af should prevent us from making this particular screw-up again. This patch also tries to limit the crash potential of a failure to write by a little bit, although it could do a better job of retaining microdescriptor bodies. Fix for bug 8822, bugfix on 0.2.4.12-alpha.
-rw-r--r--changes/bug88225
-rw-r--r--src/or/microdesc.c20
2 files changed, 22 insertions, 3 deletions
diff --git a/changes/bug8822 b/changes/bug8822
new file mode 100644
index 0000000000..c6787afe06
--- /dev/null
+++ b/changes/bug8822
@@ -0,0 +1,5 @@
+ o Major bugfixes (windows):
+ - Prevent failures on Windows Vista and later when rebuilding the
+ microdescriptor cache. Diagnosed by Robert Ransom. Fixes bug 8822;
+ bugfix on 0.2.4.12-alpha.
+
diff --git a/src/or/microdesc.c b/src/or/microdesc.c
index d9955c7b49..f99e1c88ad 100644
--- a/src/or/microdesc.c
+++ b/src/or/microdesc.c
@@ -474,15 +474,29 @@ microdesc_cache_rebuild(microdesc_cache_t *cache, int force)
smartlist_add(wrote, md);
}
+ /* We must do this unmap _before_ we call finish_writing_to_file(), or
+ * windows will not actually replace the file. */
+ if (cache->cache_content)
+ tor_munmap_file(cache->cache_content);
+
if (finish_writing_to_file(open_file) < 0) {
log_warn(LD_DIR, "Error rebuilding microdescriptor cache: %s",
strerror(errno));
+ /* Okay. Let's prevent from making things worse elsewhere. */
+ cache->cache_content = NULL;
+ HT_FOREACH(mdp, microdesc_map, &cache->map) {
+ microdesc_t *md = *mdp;
+ if (md->saved_location == SAVED_IN_CACHE) {
+ md->off = 0;
+ md->saved_location = SAVED_NOWHERE;
+ md->body = NULL;
+ md->bodylen = 0;
+ md->no_save = 1;
+ }
+ }
return -1;
}
- if (cache->cache_content)
- tor_munmap_file(cache->cache_content);
-
cache->cache_content = tor_mmap_file(cache->cache_fname);
if (!cache->cache_content && smartlist_len(wrote)) {