Skip to content

Commit

Permalink
[STORE] Add filename to corruption message
Browse files Browse the repository at this point in the history
Today we rely on the IndexOutput#toString method to print the actual
resource name we are verifying. This has a but in the 4.10.x series
that leaves us with the default toString. This commit adds the filename
to each corruption message for easier debugging.

Relates to #10062
  • Loading branch information
s1monw committed Mar 16, 2015
1 parent acd095d commit 972039c
Show file tree
Hide file tree
Showing 4 changed files with 32 additions and 18 deletions.
Expand Up @@ -56,22 +56,22 @@ static class Adler32VerifyingIndexOutput extends VerifyingIndexOutput {
final Checksum checksum = new BufferedChecksum(new Adler32());
long written;

public Adler32VerifyingIndexOutput(IndexOutput out, String adler32, long length) {
super(out);
public Adler32VerifyingIndexOutput(IndexOutput out, String name, String adler32, long length) {
super(out, name);
this.adler32 = adler32;
this.length = length;
}

@Override
public void verify() throws IOException {
if (written != length) {
throw new CorruptIndexException("expected length=" + length + " != actual length: " + written + " : file truncated?" +
" (resource=" + out + ")");
throw new CorruptIndexException("expected length=" + length + " != actual length: " + written + " : file truncated? " +
super.toString());
}
final String actualChecksum = Store.digestToString(checksum.getValue());
if (!adler32.equals(actualChecksum)) {
throw new CorruptIndexException("checksum failed (hardware problem?) : expected=" + adler32 +
" actual=" + actualChecksum + " resource=(" + out + ")");
" actual=" + actualChecksum +" " + super.toString());
}
}

Expand All @@ -97,16 +97,16 @@ static class LengthVerifyingIndexOutput extends VerifyingIndexOutput {
final long length;
long written;

public LengthVerifyingIndexOutput(IndexOutput out, long length) {
super(out);
public LengthVerifyingIndexOutput(IndexOutput out, String name, long length) {
super(out, name);
this.length = length;
}

@Override
public void verify() throws IOException {
if (written != length) {
throw new CorruptIndexException("expected length=" + length + " != actual length: " + written + " : file truncated?" +
" (resource=" + out + ")");
throw new CorruptIndexException("expected length=" + length + " != actual length: " + written + " : file truncated? " +
super.toString());
}
}

Expand Down
8 changes: 4 additions & 4 deletions src/main/java/org/elasticsearch/index/store/Store.java
Expand Up @@ -430,16 +430,16 @@ public IndexOutput createVerifyingOutput(String fileName, final StoreFileMetaDat
if (metadata.hasLegacyChecksum()) {
if (isUnreliableLegacyChecksum(metadata)) {
logger.debug("create legacy length-only output for non-write-once file {}", fileName);
output = new LegacyVerification.LengthVerifyingIndexOutput(output, metadata.length());
output = new LegacyVerification.LengthVerifyingIndexOutput(output, metadata.name(), metadata.length());
} else {
logger.debug("create legacy adler32 output for {}", fileName);
output = new LegacyVerification.Adler32VerifyingIndexOutput(output, metadata.checksum(), metadata.length());
output = new LegacyVerification.Adler32VerifyingIndexOutput(output, metadata.name(), metadata.checksum(), metadata.length());
}
} else if (metadata.checksum() == null) {
// TODO: when the file is a segments_N, we can still CRC-32 + length for more safety
// its had that checksum forever.
logger.debug("create legacy length-only output for {}", fileName);
output = new LegacyVerification.LengthVerifyingIndexOutput(output, metadata.length());
output = new LegacyVerification.LengthVerifyingIndexOutput(output, metadata.name(), metadata.length());
} else {
assert metadata.writtenBy() != null;
assert metadata.writtenBy().onOrAfter(Version.LUCENE_48);
Expand Down Expand Up @@ -1214,7 +1214,7 @@ static class LuceneVerifyingIndexOutput extends VerifyingIndexOutput {
private String actualChecksum;

LuceneVerifyingIndexOutput(StoreFileMetaData metadata, IndexOutput out) {
super(out);
super(out, metadata.name());
this.metadata = metadata;
checksumPosition = metadata.length() - 8; // the last 8 bytes are the checksum
}
Expand Down
Expand Up @@ -31,9 +31,12 @@
// do NOT optimize this class for performance
public abstract class VerifyingIndexOutput extends FilterIndexOutput {

private final String name;

/** Sole constructor */
VerifyingIndexOutput(IndexOutput out) {
VerifyingIndexOutput(IndexOutput out, String name) {
super(out);
this.name = name;
}

/**
Expand All @@ -42,4 +45,15 @@ public abstract class VerifyingIndexOutput extends FilterIndexOutput {
*/
public abstract void verify() throws IOException;

/**
* Returns the name of the resource to verfiy
*/
public String getName() {
return name;
}

public String toString() {
return "(resource=" + out + ")(name=" + name + ")"; // out.toString is buggy in 4.10.x so we also append the name here to see which file we verify
}

}
Expand Up @@ -48,7 +48,7 @@ public void testAdler32() throws Exception {
Directory dir = newDirectory();

IndexOutput o = dir.createOutput("legacy", IOContext.DEFAULT);
VerifyingIndexOutput out = new LegacyVerification.Adler32VerifyingIndexOutput(o, expectedString, 8);
VerifyingIndexOutput out = new LegacyVerification.Adler32VerifyingIndexOutput(o, "legacy", expectedString, 8);
out.writeBytes(bytes, 0, bytes.length);
out.verify();
out.close();
Expand All @@ -67,7 +67,7 @@ public void testAdler32Corrupt() throws Exception {
Directory dir = newDirectory();

IndexOutput o = dir.createOutput("legacy", IOContext.DEFAULT);
VerifyingIndexOutput out = new LegacyVerification.Adler32VerifyingIndexOutput(o, expectedString, 8);
VerifyingIndexOutput out = new LegacyVerification.Adler32VerifyingIndexOutput(o, "legacy", expectedString, 8);
out.writeBytes(corruptBytes, 0, bytes.length);
try {
out.verify();
Expand All @@ -91,7 +91,7 @@ public void testLengthOnlyOneByte() throws Exception {
Directory dir = newDirectory();

IndexOutput o = dir.createOutput("oneByte", IOContext.DEFAULT);
VerifyingIndexOutput out = new LegacyVerification.LengthVerifyingIndexOutput(o, 1);
VerifyingIndexOutput out = new LegacyVerification.LengthVerifyingIndexOutput(o, "oneByte", 1);
out.writeByte((byte) 3);
out.verify();
out.close();
Expand All @@ -104,7 +104,7 @@ public void testLengthOnlyCorrupt() throws Exception {
Directory dir = newDirectory();

IndexOutput o = dir.createOutput("oneByte", IOContext.DEFAULT);
VerifyingIndexOutput out = new LegacyVerification.LengthVerifyingIndexOutput(o, 2);
VerifyingIndexOutput out = new LegacyVerification.LengthVerifyingIndexOutput(o, "oneByte", 2);
out.writeByte((byte) 3);
try {
out.verify();
Expand Down

0 comments on commit 972039c

Please sign in to comment.