HDFS-13143. SnapshotDiff - snapshotDiffReport might be inconsistent if the snapshotDiff calculation happens between a snapshot and the current tree. Contributed by Shashikant Banerjee
This commit is contained in:
parent
727c033997
commit
55c77bf722
|
@ -139,6 +139,7 @@ import org.apache.hadoop.hdfs.protocol.SnapshotAccessControlException;
|
||||||
import org.apache.hadoop.hdfs.protocol.SnapshottableDirectoryStatus;
|
import org.apache.hadoop.hdfs.protocol.SnapshottableDirectoryStatus;
|
||||||
import org.apache.hadoop.hdfs.protocol.UnresolvedPathException;
|
import org.apache.hadoop.hdfs.protocol.UnresolvedPathException;
|
||||||
import org.apache.hadoop.hdfs.protocol.ZoneReencryptionStatus;
|
import org.apache.hadoop.hdfs.protocol.ZoneReencryptionStatus;
|
||||||
|
import org.apache.hadoop.hdfs.protocol.SnapshotDiffReport;
|
||||||
import org.apache.hadoop.hdfs.protocol.SnapshotDiffReportListing;
|
import org.apache.hadoop.hdfs.protocol.SnapshotDiffReportListing;
|
||||||
import org.apache.hadoop.hdfs.protocol.datatransfer.DataTransferProtoUtil;
|
import org.apache.hadoop.hdfs.protocol.datatransfer.DataTransferProtoUtil;
|
||||||
import org.apache.hadoop.hdfs.protocol.datatransfer.IOStreamPair;
|
import org.apache.hadoop.hdfs.protocol.datatransfer.IOStreamPair;
|
||||||
|
@ -2118,6 +2119,20 @@ public class DFSClient implements java.io.Closeable, RemotePeerFactory,
|
||||||
/**
|
/**
|
||||||
* Get the difference between two snapshots, or between a snapshot and the
|
* Get the difference between two snapshots, or between a snapshot and the
|
||||||
* current tree of a directory.
|
* current tree of a directory.
|
||||||
|
* @see ClientProtocol#getSnapshotDiffReport
|
||||||
|
*/
|
||||||
|
public SnapshotDiffReport getSnapshotDiffReport(String snapshotDir,
|
||||||
|
String fromSnapshot, String toSnapshot) throws IOException {
|
||||||
|
checkOpen();
|
||||||
|
try (TraceScope ignored = tracer.newScope("getSnapshotDiffReport")) {
|
||||||
|
return namenode
|
||||||
|
.getSnapshotDiffReport(snapshotDir, fromSnapshot, toSnapshot);
|
||||||
|
} catch (RemoteException re) {
|
||||||
|
throw re.unwrapRemoteException();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
/**
|
||||||
|
* Get the difference between two snapshots of a directory iteratively.
|
||||||
* @see ClientProtocol#getSnapshotDiffReportListing
|
* @see ClientProtocol#getSnapshotDiffReportListing
|
||||||
*/
|
*/
|
||||||
public SnapshotDiffReportListing getSnapshotDiffReportListing(
|
public SnapshotDiffReportListing getSnapshotDiffReportListing(
|
||||||
|
|
|
@ -2020,8 +2020,13 @@ public class DistributedFileSystem extends FileSystem
|
||||||
@Override
|
@Override
|
||||||
public RemoteIterator<SnapshotDiffReportListing> doCall(final Path p)
|
public RemoteIterator<SnapshotDiffReportListing> doCall(final Path p)
|
||||||
throws IOException {
|
throws IOException {
|
||||||
return new SnapshotDiffReportListingIterator(
|
if (!isValidSnapshotName(fromSnapshot) || !isValidSnapshotName(
|
||||||
getPathName(p), fromSnapshot, toSnapshot);
|
toSnapshot)) {
|
||||||
|
throw new UnsupportedOperationException("Remote Iterator is"
|
||||||
|
+ "supported for snapshotDiffReport between two snapshots");
|
||||||
|
}
|
||||||
|
return new SnapshotDiffReportListingIterator(getPathName(p),
|
||||||
|
fromSnapshot, toSnapshot);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@ -2081,9 +2086,23 @@ public class DistributedFileSystem extends FileSystem
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private boolean isValidSnapshotName(String snapshotName) {
|
||||||
|
// If any of the snapshots specified in the getSnapshotDiffReport call
|
||||||
|
// is null or empty, it points to the current tree.
|
||||||
|
return (snapshotName != null && !snapshotName.isEmpty());
|
||||||
|
}
|
||||||
|
|
||||||
private SnapshotDiffReport getSnapshotDiffReportInternal(
|
private SnapshotDiffReport getSnapshotDiffReportInternal(
|
||||||
final String snapshotDir, final String fromSnapshot,
|
final String snapshotDir, final String fromSnapshot,
|
||||||
final String toSnapshot) throws IOException {
|
final String toSnapshot) throws IOException {
|
||||||
|
// In case the diff needs to be computed between a snapshot and the current
|
||||||
|
// tree, we should not do iterative diffReport computation as the iterative
|
||||||
|
// approach might fail if in between the rpc calls the current tree
|
||||||
|
// changes in absence of the global fsn lock.
|
||||||
|
if (!isValidSnapshotName(fromSnapshot) || !isValidSnapshotName(
|
||||||
|
toSnapshot)) {
|
||||||
|
return dfs.getSnapshotDiffReport(snapshotDir, fromSnapshot, toSnapshot);
|
||||||
|
}
|
||||||
byte[] startPath = DFSUtilClient.EMPTY_BYTES;
|
byte[] startPath = DFSUtilClient.EMPTY_BYTES;
|
||||||
int index = -1;
|
int index = -1;
|
||||||
SnapshotDiffReportGenerator snapshotDiffReport;
|
SnapshotDiffReportGenerator snapshotDiffReport;
|
||||||
|
|
|
@ -1308,8 +1308,7 @@ public interface ClientProtocol {
|
||||||
String fromSnapshot, String toSnapshot) throws IOException;
|
String fromSnapshot, String toSnapshot) throws IOException;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Get the difference between two snapshots, or between a snapshot and the
|
* Get the difference between two snapshots of a directory iteratively.
|
||||||
* current tree of a directory.
|
|
||||||
*
|
*
|
||||||
* @param snapshotRoot
|
* @param snapshotRoot
|
||||||
* full path of the directory where snapshots are taken
|
* full path of the directory where snapshots are taken
|
||||||
|
|
|
@ -1539,4 +1539,17 @@ public class TestSnapshotDiffReport {
|
||||||
new DiffReportEntry(DiffType.DELETE,
|
new DiffReportEntry(DiffType.DELETE,
|
||||||
DFSUtil.string2Bytes("dir3/file3")));
|
DFSUtil.string2Bytes("dir3/file3")));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testSnapshotDiffReportRemoteIterator2() throws Exception {
|
||||||
|
final Path root = new Path("/");
|
||||||
|
hdfs.mkdirs(root);
|
||||||
|
SnapshotTestHelper.createSnapshot(hdfs, root, "s0");
|
||||||
|
try {
|
||||||
|
hdfs.snapshotDiffReportListingRemoteIterator(root, "s0", "");
|
||||||
|
} catch (Exception e) {
|
||||||
|
Assert.assertTrue(e.getMessage().contains("Remote Iterator is"
|
||||||
|
+ "supported for snapshotDiffReport between two snapshots"));
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue