HDFS-10797. Disk usage summary of snapshots causes renamed blocks to get counted twice. Contributed by Sean Mackrory.
This commit is contained in:
parent
e57fa81d95
commit
6a38d118d8
|
@ -21,6 +21,10 @@ import com.google.common.base.Preconditions;
|
|||
import org.apache.hadoop.classification.InterfaceAudience;
|
||||
import org.apache.hadoop.classification.InterfaceStability;
|
||||
import org.apache.hadoop.hdfs.server.blockmanagement.BlockStoragePolicySuite;
|
||||
import org.apache.hadoop.hdfs.server.namenode.snapshot.Snapshot;
|
||||
|
||||
import java.util.HashSet;
|
||||
import java.util.Set;
|
||||
|
||||
@InterfaceAudience.Private
|
||||
@InterfaceStability.Unstable
|
||||
|
@ -35,6 +39,8 @@ public class ContentSummaryComputationContext {
|
|||
private long yieldCount = 0;
|
||||
private long sleepMilliSec = 0;
|
||||
private int sleepNanoSec = 0;
|
||||
private Set<INode> includedNodes = new HashSet<>();
|
||||
private Set<INode> deletedSnapshottedNodes = new HashSet<>();
|
||||
|
||||
/**
|
||||
* Constructor
|
||||
|
@ -51,8 +57,8 @@ public class ContentSummaryComputationContext {
|
|||
this.fsn = fsn;
|
||||
this.limitPerRun = limitPerRun;
|
||||
this.nextCountLimit = limitPerRun;
|
||||
this.counts = new ContentCounts.Builder().build();
|
||||
this.snapshotCounts = new ContentCounts.Builder().build();
|
||||
setCounts(new ContentCounts.Builder().build());
|
||||
setSnapshotCounts(new ContentCounts.Builder().build());
|
||||
this.sleepMilliSec = sleepMicroSec/1000;
|
||||
this.sleepNanoSec = (int)((sleepMicroSec%1000)*1000);
|
||||
}
|
||||
|
@ -82,6 +88,7 @@ public class ContentSummaryComputationContext {
|
|||
}
|
||||
|
||||
// Have we reached the limit?
|
||||
ContentCounts counts = getCounts();
|
||||
long currentCount = counts.getFileCount() +
|
||||
counts.getSymlinkCount() +
|
||||
counts.getDirectoryCount() +
|
||||
|
@ -123,14 +130,22 @@ public class ContentSummaryComputationContext {
|
|||
}
|
||||
|
||||
/** Get the content counts */
|
||||
public ContentCounts getCounts() {
|
||||
public synchronized ContentCounts getCounts() {
|
||||
return counts;
|
||||
}
|
||||
|
||||
private synchronized void setCounts(ContentCounts counts) {
|
||||
this.counts = counts;
|
||||
}
|
||||
|
||||
public ContentCounts getSnapshotCounts() {
|
||||
return snapshotCounts;
|
||||
}
|
||||
|
||||
private void setSnapshotCounts(ContentCounts snapshotCounts) {
|
||||
this.snapshotCounts = snapshotCounts;
|
||||
}
|
||||
|
||||
public BlockStoragePolicySuite getBlockStoragePolicySuite() {
|
||||
Preconditions.checkState((bsps != null || fsn != null),
|
||||
"BlockStoragePolicySuite must be either initialized or available via" +
|
||||
|
@ -138,4 +153,77 @@ public class ContentSummaryComputationContext {
|
|||
return (bsps != null) ? bsps:
|
||||
fsn.getBlockManager().getStoragePolicySuite();
|
||||
}
|
||||
|
||||
/**
|
||||
* If the node is an INodeReference, resolves it to the actual inode.
|
||||
* Snapshot diffs represent renamed / moved files as different
|
||||
* INodeReferences, but the underlying INode it refers to is consistent.
|
||||
*
|
||||
* @param node
|
||||
* @return The referred INode if there is one, else returns the input
|
||||
* unmodified.
|
||||
*/
|
||||
private INode resolveINodeReference(INode node) {
|
||||
if (node.isReference() && node instanceof INodeReference) {
|
||||
return ((INodeReference)node).getReferredINode();
|
||||
}
|
||||
return node;
|
||||
}
|
||||
|
||||
/**
|
||||
* Reports that a node is about to be included in this summary. Can be used
|
||||
* either to simply report that a node has been including, or check whether
|
||||
* a node has already been included.
|
||||
*
|
||||
* @param node
|
||||
* @return true if node has already been included
|
||||
*/
|
||||
public boolean nodeIncluded(INode node) {
|
||||
INode resolvedNode = resolveINodeReference(node);
|
||||
synchronized (includedNodes) {
|
||||
if (!includedNodes.contains(resolvedNode)) {
|
||||
includedNodes.add(resolvedNode);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Schedules a node that is listed as DELETED in a snapshot's diff to be
|
||||
* included in the summary at the end of computation. See
|
||||
* {@link #tallyDeletedSnapshottedINodes()} for more context.
|
||||
*
|
||||
* @param node
|
||||
*/
|
||||
public void reportDeletedSnapshottedNode(INode node) {
|
||||
deletedSnapshottedNodes.add(node);
|
||||
}
|
||||
|
||||
/**
|
||||
* Finalizes the computation by including all nodes that were reported as
|
||||
* deleted by a snapshot but have not been already including due to other
|
||||
* references.
|
||||
* <p>
|
||||
* Nodes that get renamed are listed in the snapshot's diff as both DELETED
|
||||
* under the old name and CREATED under the new name. The computation
|
||||
* relies on nodes to report themselves as being included (via
|
||||
* {@link #nodeIncluded(INode)} as the only reliable way to determine which
|
||||
* nodes were renamed within the tree being summarized and which were
|
||||
* removed (either by deletion or being renamed outside of the tree).
|
||||
*/
|
||||
public synchronized void tallyDeletedSnapshottedINodes() {
|
||||
/* Temporarily create a new counts object so these results can then be
|
||||
added to both counts and snapshotCounts */
|
||||
ContentCounts originalCounts = getCounts();
|
||||
setCounts(new ContentCounts.Builder().build());
|
||||
for (INode node : deletedSnapshottedNodes) {
|
||||
if (!nodeIncluded(node)) {
|
||||
node.computeContentSummary(Snapshot.CURRENT_STATE_ID, this);
|
||||
}
|
||||
}
|
||||
originalCounts.addContents(getCounts());
|
||||
snapshotCounts.addContents(getCounts());
|
||||
setCounts(originalCounts);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -429,6 +429,7 @@ public abstract class INode implements INodeAttributes, Diff.Element<byte[]> {
|
|||
public final ContentSummary computeAndConvertContentSummary(int snapshotId,
|
||||
ContentSummaryComputationContext summary) {
|
||||
computeContentSummary(snapshotId, summary);
|
||||
summary.tallyDeletedSnapshottedINodes();
|
||||
final ContentCounts counts = summary.getCounts();
|
||||
final ContentCounts snapshotCounts = summary.getSnapshotCounts();
|
||||
final QuotaCounts q = getQuotaCounts();
|
||||
|
|
|
@ -628,17 +628,10 @@ public class INodeDirectory extends INodeWithAdditionalFields
|
|||
@Override
|
||||
public ContentSummaryComputationContext computeContentSummary(int snapshotId,
|
||||
ContentSummaryComputationContext summary) {
|
||||
summary.nodeIncluded(this);
|
||||
final DirectoryWithSnapshotFeature sf = getDirectoryWithSnapshotFeature();
|
||||
if (sf != null && snapshotId == Snapshot.CURRENT_STATE_ID) {
|
||||
final ContentCounts counts = new ContentCounts.Builder().build();
|
||||
// if the getContentSummary call is against a non-snapshot path, the
|
||||
// computation should include all the deleted files/directories
|
||||
sf.computeContentSummary4Snapshot(summary.getBlockStoragePolicySuite(),
|
||||
counts);
|
||||
summary.getCounts().addContents(counts);
|
||||
// Also add ContentSummary to snapshotCounts (So we can extract it
|
||||
// later from the ContentSummary of all).
|
||||
summary.getSnapshotCounts().addContents(counts);
|
||||
sf.computeContentSummary4Snapshot(summary);
|
||||
}
|
||||
final DirectoryWithQuotaFeature q = getDirectoryWithQuotaFeature();
|
||||
if (q != null && snapshotId == Snapshot.CURRENT_STATE_ID) {
|
||||
|
|
|
@ -770,6 +770,7 @@ public class INodeFile extends INodeWithAdditionalFields
|
|||
@Override
|
||||
public final ContentSummaryComputationContext computeContentSummary(
|
||||
int snapshotId, final ContentSummaryComputationContext summary) {
|
||||
summary.nodeIncluded(this);
|
||||
final ContentCounts counts = summary.getCounts();
|
||||
counts.addContent(Content.FILE, 1);
|
||||
final long fileLen = computeFileSize(snapshotId);
|
||||
|
|
|
@ -315,6 +315,7 @@ public abstract class INodeReference extends INode {
|
|||
@Override
|
||||
public ContentSummaryComputationContext computeContentSummary(int snapshotId,
|
||||
ContentSummaryComputationContext summary) {
|
||||
summary.nodeIncluded(this);
|
||||
return referred.computeContentSummary(snapshotId, summary);
|
||||
}
|
||||
|
||||
|
@ -504,6 +505,7 @@ public abstract class INodeReference extends INode {
|
|||
@Override
|
||||
public final ContentSummaryComputationContext computeContentSummary(
|
||||
int snapshotId, ContentSummaryComputationContext summary) {
|
||||
summary.nodeIncluded(this);
|
||||
final int s = snapshotId < lastSnapshotId ? snapshotId : lastSnapshotId;
|
||||
// only count storagespace for WithName
|
||||
final QuotaCounts q = computeQuotaUsage(
|
||||
|
|
|
@ -96,6 +96,7 @@ public class INodeSymlink extends INodeWithAdditionalFields {
|
|||
@Override
|
||||
public ContentSummaryComputationContext computeContentSummary(int snapshotId,
|
||||
final ContentSummaryComputationContext summary) {
|
||||
summary.nodeIncluded(this);
|
||||
summary.getCounts().addContent(Content.SYMLINK, 1);
|
||||
return summary;
|
||||
}
|
||||
|
|
|
@ -29,9 +29,9 @@ import org.apache.hadoop.classification.InterfaceAudience;
|
|||
import org.apache.hadoop.hdfs.DFSUtil;
|
||||
import org.apache.hadoop.hdfs.protocol.QuotaExceededException;
|
||||
import org.apache.hadoop.hdfs.protocol.SnapshotException;
|
||||
import org.apache.hadoop.hdfs.server.blockmanagement.BlockStoragePolicySuite;
|
||||
import org.apache.hadoop.hdfs.server.namenode.Content;
|
||||
import org.apache.hadoop.hdfs.server.namenode.ContentCounts;
|
||||
import org.apache.hadoop.hdfs.server.namenode.ContentSummaryComputationContext;
|
||||
import org.apache.hadoop.hdfs.server.namenode.INode;
|
||||
import org.apache.hadoop.hdfs.server.namenode.INodeDirectory;
|
||||
import org.apache.hadoop.hdfs.server.namenode.INodeDirectory.SnapshotAndINode;
|
||||
|
@ -220,11 +220,12 @@ public class DirectorySnapshottableFeature extends DirectoryWithSnapshotFeature
|
|||
}
|
||||
|
||||
@Override
|
||||
public void computeContentSummary4Snapshot(final BlockStoragePolicySuite bsps,
|
||||
final ContentCounts counts) {
|
||||
public void computeContentSummary4Snapshot(ContentSummaryComputationContext
|
||||
context) {
|
||||
ContentCounts counts = context.getCounts();
|
||||
counts.addContent(Content.SNAPSHOT, snapshotsByNames.size());
|
||||
counts.addContent(Content.SNAPSHOTTABLE_DIRECTORY, 1);
|
||||
super.computeContentSummary4Snapshot(bsps, counts);
|
||||
super.computeContentSummary4Snapshot(context);
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
@ -30,7 +30,6 @@ import org.apache.hadoop.classification.InterfaceAudience;
|
|||
import org.apache.hadoop.hdfs.protocol.QuotaExceededException;
|
||||
import org.apache.hadoop.hdfs.server.blockmanagement.BlockStoragePolicySuite;
|
||||
import org.apache.hadoop.hdfs.server.namenode.AclStorage;
|
||||
import org.apache.hadoop.hdfs.server.namenode.ContentCounts;
|
||||
import org.apache.hadoop.hdfs.server.namenode.ContentSummaryComputationContext;
|
||||
import org.apache.hadoop.hdfs.server.namenode.FSImageSerialization;
|
||||
import org.apache.hadoop.hdfs.server.namenode.INode;
|
||||
|
@ -629,18 +628,13 @@ public class DirectoryWithSnapshotFeature implements INode.Feature {
|
|||
return counts;
|
||||
}
|
||||
|
||||
public void computeContentSummary4Snapshot(final BlockStoragePolicySuite bsps,
|
||||
final ContentCounts counts) {
|
||||
// Create a new blank summary context for blocking processing of subtree.
|
||||
ContentSummaryComputationContext summary =
|
||||
new ContentSummaryComputationContext(bsps);
|
||||
public void computeContentSummary4Snapshot(
|
||||
ContentSummaryComputationContext context) {
|
||||
for(DirectoryDiff d : diffs) {
|
||||
for(INode deleted : d.getChildrenDiff().getList(ListType.DELETED)) {
|
||||
deleted.computeContentSummary(Snapshot.CURRENT_STATE_ID, summary);
|
||||
for(INode deletedNode : d.getChildrenDiff().getList(ListType.DELETED)) {
|
||||
context.reportDeletedSnapshottedNode(deletedNode);
|
||||
}
|
||||
}
|
||||
// Add the counts from deleted trees.
|
||||
counts.addContents(summary.getCounts());
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
@ -177,6 +177,7 @@ public class Snapshot implements Comparable<byte[]> {
|
|||
@Override
|
||||
public ContentSummaryComputationContext computeContentSummary(
|
||||
int snapshotId, ContentSummaryComputationContext summary) {
|
||||
summary.nodeIncluded(this);
|
||||
return computeDirectoryContentSummary(summary, snapshotId);
|
||||
}
|
||||
|
||||
|
|
|
@ -36,8 +36,10 @@ import java.util.Random;
|
|||
import org.apache.commons.logging.Log;
|
||||
import org.apache.commons.logging.LogFactory;
|
||||
import org.apache.hadoop.conf.Configuration;
|
||||
import org.apache.hadoop.fs.ContentSummary;
|
||||
import org.apache.hadoop.fs.FSDataOutputStream;
|
||||
import org.apache.hadoop.fs.FileStatus;
|
||||
import org.apache.hadoop.fs.FileSystem;
|
||||
import org.apache.hadoop.fs.Options.Rename;
|
||||
import org.apache.hadoop.fs.Path;
|
||||
import org.apache.hadoop.fs.permission.FsPermission;
|
||||
|
@ -2411,4 +2413,201 @@ public class TestRenameWithSnapshots {
|
|||
assertTrue(existsInDiffReport(entries, DiffType.RENAME, "foo/file2", "newDir/file2"));
|
||||
assertTrue(existsInDiffReport(entries, DiffType.RENAME, "foo/file3", "newDir/file1"));
|
||||
}
|
||||
|
||||
private void checkSpaceConsumed(String message, Path directory,
|
||||
long expectedSpace) throws Exception {
|
||||
ContentSummary summary = hdfs.getContentSummary(directory);
|
||||
assertEquals(message, expectedSpace, summary.getSpaceConsumed());
|
||||
}
|
||||
|
||||
/**
|
||||
* Runs through various combinations of renames, deletes, appends and other
|
||||
* operations in a snapshotted directory and ensures disk usage summaries
|
||||
* (e.g. du -s) are computed correctly.
|
||||
*
|
||||
* @throws Exception
|
||||
*/
|
||||
@Test (timeout=300000)
|
||||
public void testDu() throws Exception {
|
||||
File tempFile = File.createTempFile("testDu-", ".tmp");
|
||||
tempFile.deleteOnExit();
|
||||
|
||||
final FileSystem localfs = FileSystem.getLocal(conf);
|
||||
final Path localOriginal = new Path(tempFile.getPath());
|
||||
final Path dfsRoot = new Path("/testDu");
|
||||
final Path dfsOriginal = new Path(dfsRoot, "original");
|
||||
final Path dfsRenamed1 = new Path(dfsRoot, "renamed1");
|
||||
final Path dfsRenamed2 = new Path(dfsRoot, "renamed2");
|
||||
final Path dfsAppended = new Path(dfsRoot, "appended");
|
||||
|
||||
/* We will test with a single block worth of data. If we don't at least use
|
||||
a multiple of BLOCKSIZE, append operations will modify snapshotted blocks
|
||||
and other factors will come into play here that we'll have to account for */
|
||||
final long spaceIncrement = BLOCKSIZE * REPL;
|
||||
final byte[] appendData = new byte[(int) BLOCKSIZE];
|
||||
DFSTestUtil.createFile(localfs, localOriginal, BLOCKSIZE, REPL, SEED);
|
||||
|
||||
FSDataOutputStream out = null;
|
||||
long expectedSpace = 0;
|
||||
|
||||
hdfs.mkdirs(dfsRoot);
|
||||
checkSpaceConsumed("Du is wrong immediately",
|
||||
dfsRoot, 0L);
|
||||
|
||||
hdfs.copyFromLocalFile(localOriginal, dfsOriginal);
|
||||
expectedSpace += spaceIncrement;
|
||||
checkSpaceConsumed("Du is wrong after creating / copying file",
|
||||
dfsRoot, expectedSpace);
|
||||
|
||||
SnapshotTestHelper.createSnapshot(hdfs, dfsRoot, "s0");
|
||||
checkSpaceConsumed("Du is wrong after snapshotting",
|
||||
dfsRoot, expectedSpace);
|
||||
|
||||
hdfs.rename(dfsOriginal, dfsRenamed1);
|
||||
checkSpaceConsumed("Du is wrong after 1 rename",
|
||||
dfsRoot, expectedSpace);
|
||||
|
||||
hdfs.rename(dfsRenamed1, dfsRenamed2);
|
||||
checkSpaceConsumed("Du is wrong after 2 renames",
|
||||
dfsRoot, expectedSpace);
|
||||
|
||||
hdfs.delete(dfsRenamed2, false);
|
||||
checkSpaceConsumed("Du is wrong after deletion",
|
||||
dfsRoot, expectedSpace);
|
||||
|
||||
hdfs.copyFromLocalFile(localOriginal, dfsOriginal);
|
||||
expectedSpace += spaceIncrement;
|
||||
checkSpaceConsumed("Du is wrong after replacing a renamed file",
|
||||
dfsRoot, expectedSpace);
|
||||
|
||||
hdfs.copyFromLocalFile(localOriginal, dfsAppended);
|
||||
expectedSpace += spaceIncrement;
|
||||
SnapshotTestHelper.createSnapshot(hdfs, dfsRoot, "s1");
|
||||
|
||||
out = hdfs.append(dfsAppended);
|
||||
out.write(appendData);
|
||||
out.close();
|
||||
expectedSpace += spaceIncrement;
|
||||
checkSpaceConsumed("Du is wrong after 1 snapshot + append",
|
||||
dfsRoot, expectedSpace);
|
||||
|
||||
SnapshotTestHelper.createSnapshot(hdfs, dfsRoot, "s2");
|
||||
out = hdfs.append(dfsAppended);
|
||||
out.write(appendData);
|
||||
out.close();
|
||||
expectedSpace += spaceIncrement;
|
||||
checkSpaceConsumed("Du is wrong after 2 snapshot + appends",
|
||||
dfsRoot, expectedSpace);
|
||||
|
||||
SnapshotTestHelper.createSnapshot(hdfs, dfsRoot, "s3");
|
||||
out = hdfs.append(dfsAppended);
|
||||
out.write(appendData);
|
||||
out.close();
|
||||
expectedSpace += spaceIncrement;
|
||||
hdfs.rename(dfsAppended, dfsRenamed1);
|
||||
checkSpaceConsumed("Du is wrong after snapshot, append, & rename",
|
||||
dfsRoot, expectedSpace);
|
||||
hdfs.delete(dfsRenamed1, false);
|
||||
// everything but the last append is snapshotted
|
||||
expectedSpace -= spaceIncrement;
|
||||
checkSpaceConsumed("Du is wrong after snapshot, append, delete & rename",
|
||||
dfsRoot, expectedSpace);
|
||||
|
||||
hdfs.delete(dfsOriginal, false);
|
||||
hdfs.deleteSnapshot(dfsRoot, "s0");
|
||||
hdfs.deleteSnapshot(dfsRoot, "s1");
|
||||
hdfs.deleteSnapshot(dfsRoot, "s2");
|
||||
hdfs.deleteSnapshot(dfsRoot, "s3");
|
||||
expectedSpace = 0;
|
||||
checkSpaceConsumed("Du is wrong after deleting all files and snapshots",
|
||||
dfsRoot, expectedSpace);
|
||||
}
|
||||
|
||||
/**
|
||||
* Runs through various combinations of renames, deletes, appends and other
|
||||
* operations between two snapshotted directories and ensures disk usage
|
||||
* summaries (e.g. du -s) are computed correctly.
|
||||
*
|
||||
* This test currently assumes some incorrect behavior when files have been
|
||||
* moved between subdirectories of the one being queried. In the cases
|
||||
* below, only 1 block worth of data should ever actually be used. However
|
||||
* if there are 2 - 3 subdirectories that do contained or have contained
|
||||
* when snapshotted the same file, that file will be counted 2-3 times,
|
||||
* respectively, since each directory is computed independently recursively.
|
||||
*
|
||||
* @throws Exception
|
||||
*/
|
||||
@Test (timeout=300000)
|
||||
public void testDuMultipleDirs() throws Exception {
|
||||
File tempFile = File.createTempFile("testDuMultipleDirs-", "" + ".tmp");
|
||||
tempFile.deleteOnExit();
|
||||
|
||||
final FileSystem localfs = FileSystem.getLocal(conf);
|
||||
final Path localOriginal = new Path(tempFile.getPath());
|
||||
final Path dfsRoot = new Path("/testDuMultipleDirs");
|
||||
final Path snapshottable1 = new Path(dfsRoot, "snapshottable1");
|
||||
final Path snapshottable2 = new Path(dfsRoot, "snapshottable2");
|
||||
final Path nonsnapshottable = new Path(dfsRoot, "nonsnapshottable");
|
||||
final Path subdirectory = new Path(snapshottable1, "subdirectory");
|
||||
final Path dfsOriginal = new Path(snapshottable1, "file");
|
||||
final Path renamedNonsnapshottable = new Path(nonsnapshottable, "file");
|
||||
final Path renamedSnapshottable = new Path(snapshottable2, "file");
|
||||
final Path renamedSubdirectory = new Path(subdirectory, "file");
|
||||
|
||||
/* We will test with a single block worth of data. If we don't at least use
|
||||
a multiple of BLOCKSIZE, append operations will modify snapshotted blocks
|
||||
and other factors will come into play here that we'll have to account for */
|
||||
final long spaceConsumed = BLOCKSIZE * REPL;
|
||||
DFSTestUtil.createFile(localfs, localOriginal, BLOCKSIZE, REPL, SEED);
|
||||
|
||||
hdfs.mkdirs(snapshottable1);
|
||||
hdfs.mkdirs(snapshottable2);
|
||||
hdfs.mkdirs(nonsnapshottable);
|
||||
hdfs.mkdirs(subdirectory);
|
||||
checkSpaceConsumed("Du is wrong immediately",
|
||||
dfsRoot, 0L);
|
||||
|
||||
hdfs.copyFromLocalFile(localOriginal, dfsOriginal);
|
||||
checkSpaceConsumed("Du is wrong after creating / copying file",
|
||||
snapshottable1, spaceConsumed);
|
||||
|
||||
SnapshotTestHelper.createSnapshot(hdfs, snapshottable1, "s1");
|
||||
checkSpaceConsumed("Du is wrong in original dir after 1st snapshot",
|
||||
snapshottable1, spaceConsumed);
|
||||
|
||||
hdfs.rename(dfsOriginal, renamedNonsnapshottable);
|
||||
checkSpaceConsumed("Du is wrong in original dir after 1st rename",
|
||||
snapshottable1, spaceConsumed);
|
||||
checkSpaceConsumed("Du is wrong in non-snapshottable dir after 1st rename",
|
||||
nonsnapshottable, spaceConsumed);
|
||||
checkSpaceConsumed("Du is wrong in root dir after 1st rename",
|
||||
dfsRoot, spaceConsumed);
|
||||
|
||||
hdfs.rename(renamedNonsnapshottable, renamedSnapshottable);
|
||||
checkSpaceConsumed("Du is wrong in original dir after 2nd rename",
|
||||
snapshottable1, spaceConsumed);
|
||||
checkSpaceConsumed("Du is wrong in non-snapshottable dir after 2nd rename",
|
||||
nonsnapshottable, 0);
|
||||
checkSpaceConsumed("Du is wrong in snapshottable dir after 2nd rename",
|
||||
snapshottable2, spaceConsumed);
|
||||
checkSpaceConsumed("Du is wrong in root dir after 2nd rename",
|
||||
dfsRoot, spaceConsumed);
|
||||
|
||||
SnapshotTestHelper.createSnapshot(hdfs, snapshottable2, "s2");
|
||||
hdfs.rename(renamedSnapshottable, renamedSubdirectory);
|
||||
checkSpaceConsumed("Du is wrong in original dir after 3rd rename",
|
||||
snapshottable1, spaceConsumed);
|
||||
checkSpaceConsumed("Du is wrong in snapshottable dir after 3rd rename",
|
||||
snapshottable2, spaceConsumed);
|
||||
checkSpaceConsumed("Du is wrong in original subdirectory after 3rd rename",
|
||||
subdirectory, spaceConsumed);
|
||||
checkSpaceConsumed("Du is wrong in root dir after 3rd rename",
|
||||
dfsRoot, spaceConsumed);
|
||||
|
||||
hdfs.delete(renamedSubdirectory, false);
|
||||
hdfs.deleteSnapshot(snapshottable1, "s1");
|
||||
hdfs.deleteSnapshot(snapshottable2, "s2");
|
||||
checkSpaceConsumed("Du is wrong after deleting all files and snapshots",
|
||||
dfsRoot, 0);
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue