From: Alexandre Oliva <oliva@gnu.org>
To: Chris Mason <clmason@fusionio.com>
Cc: Samuel Just <sam.just@inktank.com>,
"linux-btrfs\@vger.kernel.org" <linux-btrfs@vger.kernel.org>,
"ceph-devel\@vger.kernel.org" <ceph-devel@vger.kernel.org>
Subject: Re: corruption of active mmapped files in btrfs snapshots
Date: Sat, 23 Mar 2013 06:47:26 -0300 [thread overview]
Message-ID: <or620ia1n5.fsf@livre.home> (raw)
In-Reply-To: <20130322171214.27874.48118@localhost.localdomain> (Chris Mason's message of "Fri, 22 Mar 2013 13:12:14 -0400")
[-- Attachment #1: Type: text/plain, Size: 652 bytes --]
On Mar 22, 2013, Chris Mason <clmason@fusionio.com> wrote:
> Quoting Samuel Just (2013-03-22 13:06:41)
>> Incomplete writes for leveldb should just result in lost updates, not
>> corruption.
> In this case, I think Alexandre is scanning for zeros in the file.
Yup, the symptom is zeros at the end of a page, with nonzeros on the
subsequent page, which indicates that the writes to the previous page
were dropped.
What I actually do is to iterate over the entire database, which will
error out when the block header is found to be corrupted. I use this
program I wrote (also hereby provided under GNU GPLv3+) to check the
database for corruption.
[-- Warning: decoded text below may be mangled, UTF-8 assumed --]
[-- Attachment #2: dbck.cc --]
[-- Type: text/x-c++src, Size: 3237 bytes --]
#include <assert.h>
#include <iostream>
#include "leveldb/db.h"
int main(int argc, char *argv[]) {
bool paranoid = false;
bool dump = false;
bool repair = false;
bool quiet = false;
int i = 0;
int errors = 0;
if (argc == 1) {
usage:
std::cout << "usage: [flags] dbname [flags] ..." << std::endl
<< "-d --dump dump database contents" << std::endl
<< "-r --repair repair database" << std::endl
<< "-p --paranoid enable paranoid mode" << std::endl
<< "-l --lax disable paranoid mode (default)" << std::endl
<< "-q --quiet enable quiet mode" << std::endl
<< "-v --verbose disable quiet mode (default)" << std::endl
<< "-h --help show this message and exit" << std::endl
<< "dbname check, dump and repair" << std::endl
<< std::endl
<< "exit status is the number of errors" << std::endl;
return errors;
}
for (i++; i < argc; i++) {
if (argv[i][0] == '-') {
if (strcmp (argv[i], "--dump") == 0
|| strcmp (argv[i], "-d") == 0)
dump = true;
else if (strcmp (argv[i], "--repair") == 0
|| strcmp (argv[i], "-r") == 0)
repair = true;
else if (strcmp (argv[i], "--paranoid") == 0
|| strcmp (argv[i], "-p") == 0)
paranoid = true;
else if (strcmp (argv[i], "--lax") == 0
|| strcmp (argv[i], "-l") == 0)
paranoid = false;
else if (strcmp (argv[i], "--quiet") == 0
|| strcmp (argv[i], "-q") == 0)
quiet = true;
else if (strcmp (argv[i], "--verbose") == 0
|| strcmp (argv[i], "-v") == 0)
quiet = false;
else if (strcmp (argv[i], "--help") == 0
|| strcmp (argv[i], "-h") == 0)
goto usage;
else {
std::cerr << "unrecognized option: " << argv[i] << std::endl;
goto usage;
}
} else {
if (!quiet)
std::cout << argv[i] << std::endl;
leveldb::DB* db;
leveldb::Options options;
options.paranoid_checks = paranoid;
leveldb::Status status = leveldb::DB::Open(options, argv[i], &db);
bool bad = false;
if (!status.ok()) {
std::cerr << status.ToString() << std::endl;
bad = true;
} else {
leveldb::ReadOptions rdopt;
rdopt.verify_checksums = paranoid;
rdopt.fill_cache = false;
leveldb::Iterator* it = db->NewIterator(rdopt);
int count = 0;
try {
for (it->SeekToFirst(); it->Valid(); it->Next()) {
count++;
if (dump)
std::cout << it->key().ToString() << ": "
<< it->value().ToString() << std::endl;
else if (!quiet && count % 1000 == 0)
std::cout << count << " entries\r" << std::flush;
}
if (!it->status().ok()) {
std::cerr << it->status().ToString() << std::endl;
bad = true;
}
} catch (...) {
std::cerr << "caught an exception" << std::endl;
}
delete it;
if (!quiet)
std::cout << count << " entries" << std::endl;
}
delete db;
if (bad) {
errors++;
if (repair) {
if (!quiet)
std::cout << "repairing..." << std::endl;
status = RepairDB(argv[i], options);
if (!status.ok()) {
std::cerr << status.ToString() << std::endl;
errors++;
}
} else if (!quiet)
std::cout << "use --repair to repair" << std::endl;
}
}
}
return errors;
}
[-- Attachment #3: Type: text/plain, Size: 258 bytes --]
--
Alexandre Oliva, freedom fighter http://FSFLA.org/~lxoliva/
You must be the change you wish to see in the world. -- Gandhi
Be Free! -- http://FSFLA.org/ FSF Latin America board member
Free Software Evangelist Red Hat Brazil Compiler Engineer
next prev parent reply other threads:[~2013-03-23 9:48 UTC|newest]
Thread overview: 28+ messages / expand[flat|nested] mbox.gz Atom feed top
2013-03-18 21:14 corruption of active mmapped files in btrfs snapshots Alexandre Oliva
2013-03-18 22:43 ` Alexandre Oliva
2013-03-18 22:52 ` Chris Mason
2013-03-19 5:20 ` Alexandre Oliva
2013-03-19 12:09 ` Chris Mason
2013-03-19 17:29 ` Sage Weil
2013-03-19 19:26 ` Alexandre Oliva
2013-03-19 19:26 ` Alexandre Oliva
2013-03-20 1:58 ` Alexandre Oliva
2013-03-21 7:14 ` Alexandre Oliva
2013-03-21 18:06 ` Chris Mason
2013-03-21 23:06 ` Chris Mason
2013-03-22 5:27 ` Alexandre Oliva
2013-03-22 12:07 ` Chris Mason
2013-03-22 14:17 ` Alexandre Oliva
2013-03-22 14:26 ` Chris Mason
2013-03-22 17:06 ` Samuel Just
2013-03-22 17:12 ` Chris Mason
2013-03-23 9:47 ` Alexandre Oliva [this message]
2013-03-22 17:08 ` David Sterba
2013-03-23 9:48 ` Alexandre Oliva
2013-03-25 15:33 ` David Sterba
2013-03-22 17:18 ` Sage Weil
2013-03-22 18:07 ` Chris Mason
2013-03-22 20:31 ` Chris Mason
2013-03-26 0:08 ` Chris Mason
2013-03-29 9:56 ` Alexandre Oliva
2013-03-29 11:35 ` Chris Mason
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=or620ia1n5.fsf@livre.home \
--to=oliva@gnu.org \
--cc=ceph-devel@vger.kernel.org \
--cc=clmason@fusionio.com \
--cc=linux-btrfs@vger.kernel.org \
--cc=sam.just@inktank.com \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox