From 8fb5b2c6e85aece6419c28cef278d1ae4204520f Mon Sep 17 00:00:00 2001 From: Michael Vrable Date: Mon, 14 Jul 2008 15:49:18 -0700 Subject: [PATCH] Add the --rebuild-statcache option. Add an option which forces cumulus to re-read all files, even if they seem not to have changed. This has two main purposes: first, it helps to rebuild the contents of the statcache from data actually on disk, and as such is useful for adding object size annotations to files which haven't changed (ordinarily, the straight re-use of data from the statcache prevents this). Second, it can be used to detect some simple forms of data corruption; if a file has not changed (according to stat information) but the checksum doesn't match the old value in the statcache file, a warning is printed. --- scandir.cc | 26 +++++++++++++++++++++++++- 1 file changed, 25 insertions(+), 1 deletion(-) diff --git a/scandir.cc b/scandir.cc index a2a7a49..10e908b 100644 --- a/scandir.cc +++ b/scandir.cc @@ -96,6 +96,8 @@ std::list searches; // Directories we don't want to save, but bool relative_paths = true; +bool flag_rebuild_statcache = false; + /* Whether verbose output is enabled. */ bool verbose = false; @@ -154,7 +156,9 @@ int64_t dumpfile(int fd, dictionary &file_info, const string &path, if (found) old_blocks = metawriter->get_blocks(); - if (found && metawriter->is_unchanged(&stat_buf)) { + if (found + && !flag_rebuild_statcache + && metawriter->is_unchanged(&stat_buf)) { cached = true; /* If any of the blocks in the object have been expired, then we should @@ -285,6 +289,22 @@ int64_t dumpfile(int fd, dictionary &file_info, const string &path, file_info["checksum"] = hash.checksum_str(); } + // Sanity check: if we are rebuilding the statcache, but the file looks + // like it hasn't changed, then the newly-computed checksum should match + // the checksum in the statcache. If not, we have possible disk corruption + // and report a warning. + if (flag_rebuild_statcache) { + if (found && file_info["checksum"] != metawriter->get_checksum()) { + fprintf(stderr, + "Warning: Checksum for %s does not match expected value\n" + " expected: %s\n" + " actual: %s\n", + path.c_str(), + metawriter->get_checksum().c_str(), + file_info["checksum"].c_str()); + } + } + if (verbose && status != NULL) printf(" [%s]\n", status); @@ -639,6 +659,7 @@ int main(int argc, char *argv[]) {"full-metadata", 0, 0, 0}, // 8 {"tmpdir", 1, 0, 0}, // 9 {"upload-script", 1, 0, 0}, // 10 + {"rebuild-statcache", 0, 0, 0}, // 11 // Aliases for short options {"verbose", 0, 0, 'v'}, {NULL, 0, 0, 0}, @@ -690,6 +711,9 @@ int main(int argc, char *argv[]) case 10: // --upload-script backup_script = optarg; break; + case 11: // --rebuild-statcache + flag_rebuild_statcache = true; + break; default: fprintf(stderr, "Unhandled long option!\n"); return 1; -- 2.20.1