From 96d6b516b2468fce346490e0b95931d1759b3d33 Mon Sep 17 00:00:00 2001 From: Zhe Zhang Date: Thu, 10 Sep 2015 16:31:37 -0700 Subject: [PATCH] HDFS-8853. Erasure Coding: Provide ECSchema validation when setting EC policy. Contributed by J.Andreina. Change-Id: I9211d9728480225a407d82e6c0bea1a928adfa11 --- .../hadoop-hdfs/CHANGES-HDFS-EC-7285.txt | 3 +++ .../server/namenode/FSDirErasureCodingOp.java | 22 ++++++++++++++++++ .../hdfs/TestErasureCodingPolicies.java | 23 +++++++++++++++++++ 3 files changed, 48 insertions(+) diff --git a/hadoop-hdfs-project/hadoop-hdfs/CHANGES-HDFS-EC-7285.txt b/hadoop-hdfs-project/hadoop-hdfs/CHANGES-HDFS-EC-7285.txt index 2f133103e63..f49a97494c0 100755 --- a/hadoop-hdfs-project/hadoop-hdfs/CHANGES-HDFS-EC-7285.txt +++ b/hadoop-hdfs-project/hadoop-hdfs/CHANGES-HDFS-EC-7285.txt @@ -415,3 +415,6 @@ HDFS-8833. Erasure coding: store EC schema and cell size in INodeFile and eliminate notion of EC zones. (zhz) + + HDFS-8853. Erasure Coding: Provide ECSchema validation when setting EC + policy. (andreina via zhz) diff --git a/hadoop-hdfs-project/hadoop-hdfs/src/main/java/org/apache/hadoop/hdfs/server/namenode/FSDirErasureCodingOp.java b/hadoop-hdfs-project/hadoop-hdfs/src/main/java/org/apache/hadoop/hdfs/server/namenode/FSDirErasureCodingOp.java index 4162760d2a5..d39da28d988 100644 --- a/hadoop-hdfs-project/hadoop-hdfs/src/main/java/org/apache/hadoop/hdfs/server/namenode/FSDirErasureCodingOp.java +++ b/hadoop-hdfs-project/hadoop-hdfs/src/main/java/org/apache/hadoop/hdfs/server/namenode/FSDirErasureCodingOp.java @@ -28,6 +28,8 @@ import com.google.common.base.Preconditions; import com.google.common.collect.Lists; + +import org.apache.hadoop.HadoopIllegalArgumentException; import org.apache.hadoop.fs.XAttr; import org.apache.hadoop.fs.XAttrSetFlag; import org.apache.hadoop.fs.permission.FsAction; @@ -105,6 +107,26 @@ static List createErasureCodingPolicyXAttr(final FSNamesystem fsn, // System default erasure coding policy will be used since no specified. if (ecPolicy == null) { ecPolicy = ErasureCodingPolicyManager.getSystemDefaultPolicy(); + } else { + // If ecPolicy is specified check if it is one among active policies. + boolean validPolicy = false; + ErasureCodingPolicy[] activePolicies = + FSDirErasureCodingOp.getErasureCodingPolicies(fsd.getFSNamesystem()); + for (ErasureCodingPolicy activePolicy : activePolicies) { + if (activePolicy.equals(ecPolicy)) { + validPolicy = true; + break; + } + } + if (!validPolicy) { + List ecPolicyNames = new ArrayList(); + for (ErasureCodingPolicy activePolicy : activePolicies) { + ecPolicyNames.add(activePolicy.getName()); + } + throw new HadoopIllegalArgumentException("Policy [ " + + ecPolicy.getName()+ " ] does not match any of the " + + "supported policies. Please select any one of " + ecPolicyNames); + } } final XAttr ecXAttr; diff --git a/hadoop-hdfs-project/hadoop-hdfs/src/test/java/org/apache/hadoop/hdfs/TestErasureCodingPolicies.java b/hadoop-hdfs-project/hadoop-hdfs/src/test/java/org/apache/hadoop/hdfs/TestErasureCodingPolicies.java index f60d77d8bd5..ed41f7aee67 100644 --- a/hadoop-hdfs-project/hadoop-hdfs/src/test/java/org/apache/hadoop/hdfs/TestErasureCodingPolicies.java +++ b/hadoop-hdfs-project/hadoop-hdfs/src/test/java/org/apache/hadoop/hdfs/TestErasureCodingPolicies.java @@ -26,6 +26,7 @@ import org.apache.hadoop.hdfs.server.namenode.FSNamesystem; import org.apache.hadoop.hdfs.server.namenode.INode; import org.apache.hadoop.hdfs.protocol.ErasureCodingPolicy; +import org.apache.hadoop.io.erasurecode.ECSchema; import org.junit.After; import org.junit.Before; import org.junit.Test; @@ -208,4 +209,26 @@ private void verifyErasureCodingInfo( assertEquals("Actually used ecPolicy should be equal with target ecPolicy", usingECPolicy, ecPolicy); } + + @Test + public void testCreationErasureCodingZoneWithInvalidPolicy() + throws IOException { + ECSchema rsSchema = new ECSchema("rs", 4, 2); + String policyName = "RS-4-2-128k"; + int cellSize = 128 * 1024; + ErasureCodingPolicy ecPolicy= + new ErasureCodingPolicy(policyName,rsSchema,cellSize); + String src = "/ecZone4-2"; + final Path ecDir = new Path(src); + try { + fs.mkdir(ecDir, FsPermission.getDirDefault()); + fs.getClient().setErasureCodingPolicy(src, ecPolicy); + fail("HadoopIllegalArgumentException should be thrown for" + + "setting an invalid erasure coding policy"); + } catch (Exception e) { + assertExceptionContains("Policy [ RS-4-2-128k ] does not match " + + "any of the supported policies",e); + } + } + }