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.UnresolvedPathException;
|
||||
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.datatransfer.DataTransferProtoUtil;
|
||||
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
|
||||
* 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
|
||||
*/
|
||||
public SnapshotDiffReportListing getSnapshotDiffReportListing(
|
||||
|
|
|
@ -2020,8 +2020,13 @@ public class DistributedFileSystem extends FileSystem
|
|||
@Override
|
||||
public RemoteIterator<SnapshotDiffReportListing> doCall(final Path p)
|
||||
throws IOException {
|
||||
return new SnapshotDiffReportListingIterator(
|
||||
getPathName(p), fromSnapshot, toSnapshot);
|
||||
if (!isValidSnapshotName(fromSnapshot) || !isValidSnapshotName(
|
||||
toSnapshot)) {
|
||||
throw new UnsupportedOperationException("Remote Iterator is"
|
||||
+ "supported for snapshotDiffReport between two snapshots");
|
||||
}
|
||||
return new SnapshotDiffReportListingIterator(getPathName(p),
|
||||
fromSnapshot, toSnapshot);
|
||||
}
|
||||
|
||||
@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(
|
||||
final String snapshotDir, final String fromSnapshot,
|
||||
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;
|
||||
int index = -1;
|
||||
SnapshotDiffReportGenerator snapshotDiffReport;
|
||||
|
|
|
@ -1308,8 +1308,7 @@ public interface ClientProtocol {
|
|||
String fromSnapshot, String toSnapshot) throws IOException;
|
||||
|
||||
/**
|
||||
* Get the difference between two snapshots, or between a snapshot and the
|
||||
* current tree of a directory.
|
||||
* Get the difference between two snapshots of a directory iteratively.
|
||||
*
|
||||
* @param snapshotRoot
|
||||
* full path of the directory where snapshots are taken
|
||||
|
|
|
@ -1539,4 +1539,17 @@ public class TestSnapshotDiffReport {
|
|||
new DiffReportEntry(DiffType.DELETE,
|
||||
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