Skip to content

Commit 1ff7a65

Browse files
authored
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 <[email protected]> Signed-off-by: Ayush Saxena <[email protected]>
1 parent 9e3d5c7 commit 1ff7a65

File tree

2 files changed

+51
-0
lines changed

2 files changed

+51
-0
lines changed

hadoop-hdfs-project/hadoop-hdfs-rbf/src/main/java/org/apache/hadoop/hdfs/server/federation/router/RouterClientProtocol.java

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -614,6 +614,11 @@ public boolean rename(final String src, final String dst)
614614
new Class<?>[] {String.class, String.class},
615615
new RemoteParam(), dstParam);
616616
if (isMultiDestDirectory(src)) {
617+
if (locs.size() != srcLocations.size()) {
618+
throw new IOException("Rename of " + src + " to " + dst + " is not"
619+
+ " allowed. The number of remote locations for both source and"
620+
+ " target should be same.");
621+
}
617622
return rpcClient.invokeAll(locs, method);
618623
} else {
619624
return rpcClient.invokeSequential(locs, method, Boolean.class,
@@ -641,6 +646,11 @@ public void rename2(final String src, final String dst,
641646
new Class<?>[] {String.class, String.class, options.getClass()},
642647
new RemoteParam(), dstParam, options);
643648
if (isMultiDestDirectory(src)) {
649+
if (locs.size() != srcLocations.size()) {
650+
throw new IOException("Rename of " + src + " to " + dst + " is not"
651+
+ " allowed. The number of remote locations for both source and"
652+
+ " target should be same.");
653+
}
644654
rpcClient.invokeConcurrent(locs, method);
645655
} else {
646656
rpcClient.invokeSequential(locs, method, null, null);

hadoop-hdfs-project/hadoop-hdfs-rbf/src/test/java/org/apache/hadoop/hdfs/server/federation/router/TestRouterRPCMultipleDestinationMountTableResolver.java

Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -720,6 +720,47 @@ public void testWriteWithUnavailableSubCluster() throws IOException {
720720
}
721721
}
722722

723+
/**
724+
* Test rename a dir from src dir (mapped to both ns0 and ns1) to ns0.
725+
*/
726+
@Test
727+
public void testRenameWithMultiDestinations() throws Exception {
728+
//create a mount point with multiple destinations
729+
String srcDir = "/mount-source-dir";
730+
Path path = new Path(srcDir);
731+
Map<String, String> destMap = new HashMap<>();
732+
destMap.put("ns0", srcDir);
733+
destMap.put("ns1", srcDir);
734+
nnFs0.mkdirs(path);
735+
nnFs1.mkdirs(path);
736+
MountTable addEntry =
737+
MountTable.newInstance(srcDir, destMap);
738+
addEntry.setDestOrder(DestinationOrder.RANDOM);
739+
assertTrue(addMountTable(addEntry));
740+
741+
//create a mount point with a single destinations ns0
742+
String targetDir = "/ns0_test";
743+
nnFs0.mkdirs(new Path(targetDir));
744+
MountTable addDstEntry = MountTable.newInstance(targetDir,
745+
Collections.singletonMap("ns0", targetDir));
746+
assertTrue(addMountTable(addDstEntry));
747+
748+
//mkdir sub dirs in srcDir mapping ns0 & ns1
749+
routerFs.mkdirs(new Path(srcDir + "/dir1"));
750+
routerFs.mkdirs(new Path(srcDir + "/dir1/dir_1"));
751+
routerFs.mkdirs(new Path(srcDir + "/dir1/dir_2"));
752+
routerFs.mkdirs(new Path(targetDir));
753+
754+
//try to rename sub dir in srcDir (mapping to ns0 & ns1) to targetDir
755+
// (mapping ns0)
756+
LambdaTestUtils.intercept(IOException.class, "The number of" +
757+
" remote locations for both source and target should be same.",
758+
() -> {
759+
routerFs.rename(new Path(srcDir + "/dir1/dir_1"),
760+
new Path(targetDir));
761+
});
762+
}
763+
723764
/**
724765
* Test to verify rename operation on directories in case of multiple
725766
* destinations.

0 commit comments

Comments
 (0)