Note: "permalinks" may not be as permanent as we would like,
direct links of old sources may well be a few messages off.
Greetings, I am a new member on this list and I've been looking into this problem also. I understand that this is not a bug in DRBD, but that the resource usage patterns of DRBD can affect the outcome of this trimtester program. My main goal is to eliminate false positives. I've implemented a different strategy for checking corruption with only some minor changes to trimtester.cpp: By ensuring that no zero bytes are written to the files, checking for corruption can be detected by looking for a single zero byte. I also corrected some problems with the buffer overrun in writeAtomically(). Since many of the original problems were pointed out on this list, I post the differences here for anyone who might be interested. Comments graciously requested and accepted. This is a diff with the original trimtester.cpp forked from Algoria's repo: $ git diff 48c44d5beb88c56e003f776d79ab30781fa90c8e 97f7c179e5220c94ccc486fe3f49c21ad9c4a8c3 trimtester.cpp diff --git a/trimtester.cpp b/trimtester.cpp index d753741..2930683 100644 --- a/trimtester.cpp +++ b/trimtester.cpp @@ -217,25 +217,14 @@ private: filename.append(file); MMapedFile mmap(filename.c_str()); if (mmap.loaded()) { - bool corrupted = false; - // Detect all 512-bytes page inside the file filled by 0 -> can be caused by a buggy Trim - for (unsigned i = 0; !corrupted && i < mmap.len(); i += 512) { - if (mmap.len() - i > 4) { // only check page > 4-bytes to avoid false positive - bool pagecorrupted = true; - for (unsigned j = i; j < mmap.len() && j < (i + 512); ++j) { - if (mmap.content()[j] != 0) - pagecorrupted = false; - } - if (pagecorrupted) - corrupted = true; - + for (const char *p = mmap.content(); p < mmap.content() + mmap.len(); p++) { + if (*p == 0) { + // no zero bytes should be in file because none were written + std::cerr << "Corrupted file found: " << filename + << ", zero byte in file at byte address: " << p - mmap.content() <<std::endl; + exit(1); } } - if (corrupted) { - std::cerr << "Corrupted file found: " << filename << std::endl; - exit(1); - } - } } @@ -266,19 +255,21 @@ void writeAtomically(const std::string &dataDir, unsigned folder, unsigned file, std::string destFile = ss.str(); ss << ".tmp"; std::string tmpFile = ss.str(); - unsigned char buff[65535]; + unsigned char buff[64*1024]; - for (unsigned i = 0; i < 65536; ++i) { + for (unsigned i = 0; i < sizeof(buff); ++i) { buff[i] = (seed + i) % 256; + if (buff[i] == 0) + buff[i] = 0xff; // no zero bytes will be written } { // write file1.bin.tmp FILE *file = fopen(tmpFile.c_str(), "wb"); assert(file != NULL); - uint64_t sizeToWrite = size; + int64_t sizeToWrite = size; // because uint64_t is ALWAYS >= zero while (sizeToWrite > 0) { - uint64_t toWrite = (sizeToWrite > 65536 ? 65536 : sizeToWrite); - uint64_t nb = fwrite(buff, 1, toWrite, file); + size_t toWrite = (sizeToWrite > sizeof(buff) ? sizeof(buff) : sizeToWrite); + size_t nb = fwrite(buff, 1, toWrite, file); if (nb != toWrite) { std::cerr << "Disk full, rm folder & restart the test" << std::endl; exit(0); $ This code can be found at https://github.com/artisan-digital/trimtester There were other mods in between the fork and this version. Thanks for reading, Robert L