HDFS-16954. RBF: The operation of renaming a multi-subcluster directory to a single-cluster directory should throw ioexception. (#5483). Contributed by Max Xie.

Reviewed-by: Inigo Goiri <inigoiri@apache.org>
Signed-off-by: Ayush Saxena <ayushsaxena@apache.org>
This commit is contained in:
Neil 2023-04-20 17:49:18 +08:00 committed by GitHub
parent 9e3d5c754b
commit 1ff7a65b9f
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
2 changed files with 51 additions and 0 deletions

View File

@ -614,6 +614,11 @@ public boolean rename(final String src, final String dst)
new Class<?>[] {String.class, String.class},
new RemoteParam(), dstParam);
if (isMultiDestDirectory(src)) {
if (locs.size() != srcLocations.size()) {
throw new IOException("Rename of " + src + " to " + dst + " is not"
+ " allowed. The number of remote locations for both source and"
+ " target should be same.");
}
return rpcClient.invokeAll(locs, method);
} else {
return rpcClient.invokeSequential(locs, method, Boolean.class,
@ -641,6 +646,11 @@ public void rename2(final String src, final String dst,
new Class<?>[] {String.class, String.class, options.getClass()},
new RemoteParam(), dstParam, options);
if (isMultiDestDirectory(src)) {
if (locs.size() != srcLocations.size()) {
throw new IOException("Rename of " + src + " to " + dst + " is not"
+ " allowed. The number of remote locations for both source and"
+ " target should be same.");
}
rpcClient.invokeConcurrent(locs, method);
} else {
rpcClient.invokeSequential(locs, method, null, null);

View File

@ -720,6 +720,47 @@ public void testWriteWithUnavailableSubCluster() throws IOException {
}
}
/**
* Test rename a dir from src dir (mapped to both ns0 and ns1) to ns0.
*/
@Test
public void testRenameWithMultiDestinations() throws Exception {
//create a mount point with multiple destinations
String srcDir = "/mount-source-dir";
Path path = new Path(srcDir);
Map<String, String> destMap = new HashMap<>();
destMap.put("ns0", srcDir);
destMap.put("ns1", srcDir);
nnFs0.mkdirs(path);
nnFs1.mkdirs(path);
MountTable addEntry =
MountTable.newInstance(srcDir, destMap);
addEntry.setDestOrder(DestinationOrder.RANDOM);
assertTrue(addMountTable(addEntry));
//create a mount point with a single destinations ns0
String targetDir = "/ns0_test";
nnFs0.mkdirs(new Path(targetDir));
MountTable addDstEntry = MountTable.newInstance(targetDir,
Collections.singletonMap("ns0", targetDir));
assertTrue(addMountTable(addDstEntry));
//mkdir sub dirs in srcDir mapping ns0 & ns1
routerFs.mkdirs(new Path(srcDir + "/dir1"));
routerFs.mkdirs(new Path(srcDir + "/dir1/dir_1"));
routerFs.mkdirs(new Path(srcDir + "/dir1/dir_2"));
routerFs.mkdirs(new Path(targetDir));
//try to rename sub dir in srcDir (mapping to ns0 & ns1) to targetDir
// (mapping ns0)
LambdaTestUtils.intercept(IOException.class, "The number of" +
" remote locations for both source and target should be same.",
() -> {
routerFs.rename(new Path(srcDir + "/dir1/dir_1"),
new Path(targetDir));
});
}
/**
* Test to verify rename operation on directories in case of multiple
* destinations.