ソースを参照

HADOOP-4254. -setSpaceQuota command does not convert "TB" extenstion to
terabytes properly. Implementation now uses StringUtils for parsing this.


git-svn-id: https://svn.apache.org/repos/asf/hadoop/core/branches/branch-0.19@699425 13f79535-47bb-0310-9956-ffa450edef68

Raghu Angadi 16 年 前
コミット
46131a34c9

+ 4 - 0
CHANGES.txt

@@ -737,6 +737,10 @@ Release 0.19.0 - Unreleased
     HADOOP-4280. Fix conversions between seconds in C and milliseconds in 
     Java for access times for files. (Pete Wyckoff via rangadi)
 
+    HADOOP-4254. -setSpaceQuota command does not convert "TB" extenstion to
+    terabytes properly. Implementation now uses StringUtils for parsing this.
+    (Raghu Angadi)
+
 Release 0.18.2 - Unreleased
 
   BUG FIXES

+ 9 - 4
src/core/org/apache/hadoop/util/StringUtils.java

@@ -563,7 +563,7 @@ public class StringUtils {
     EXA(PETA.value << 10);
 
     public final long value;
-    public final long symbol;
+    public final char symbol;
 
     TraditionalBinaryPrefix(long value) {
       this.value = value;
@@ -601,9 +601,14 @@ public class StringUtils {
       final char lastchar = s.charAt(lastpos);
       if (Character.isDigit(lastchar))
         return Long.parseLong(s);
-      else
-        return TraditionalBinaryPrefix.valueOf(lastchar).value
-               * Long.parseLong(s.substring(0, lastpos));
+      else {
+        long prefix = TraditionalBinaryPrefix.valueOf(lastchar).value;
+        long num = Long.parseLong(s.substring(0, lastpos));
+        if (num > (Long.MAX_VALUE/prefix) || num < (Long.MIN_VALUE/prefix)) {
+          throw new IllegalArgumentException(s + " does not fit in a Long");
+        }
+        return num * prefix;
+      }
     }
   }
   

+ 4 - 19
src/hdfs/org/apache/hadoop/hdfs/tools/DFSAdmin.java

@@ -36,6 +36,7 @@ import org.apache.hadoop.fs.shell.Command;
 import org.apache.hadoop.fs.shell.CommandFormat;
 import org.apache.hadoop.ipc.RPC;
 import org.apache.hadoop.ipc.RemoteException;
+import org.apache.hadoop.util.StringUtils;
 import org.apache.hadoop.util.ToolRunner;
 
 /**
@@ -193,8 +194,8 @@ public class DFSAdmin extends FsShell {
       "\tSet the dik space quota <quota> for each directory <dirName>.\n" + 
       "\t\tThe directory quota is a long integer that puts a hard limit " +
       "on the number of names in the directory tree.\n" +
-      "\t\tQuota can also be speciefied with MB, GB, or TB suffix" +
-      " (e.g. 100GB, 20TB).\n" + 
+      "\t\tQuota can also be speciefied with a binary prefix for terabytes, " +
+      " petabytes etc (e.g. 50t is 50TB, 5m is 5MB, 3p is 3PB).\n" + 
       "\t\tBest effort for the directory, with faults reported if\n" +
       "\t\t1. N is not a positive integer, or\n" +
       "\t\t2. user is not an administrator, or\n" +
@@ -208,24 +209,8 @@ public class DFSAdmin extends FsShell {
       super(fs);
       CommandFormat c = new CommandFormat(NAME, 2, Integer.MAX_VALUE);
       List<String> parameters = c.parse(args, pos);
-      long multiplier = 1;
       String str = parameters.remove(0).trim();
-      if (str.endsWith("TB")) {
-        multiplier = 1024 * 1024 * 1024 * 1024;
-      } else if (str.endsWith("GB")) {
-        multiplier = 1024 * 1024 * 1024;
-      } else if (str.endsWith("MB")) {
-        multiplier = 1024 * 1024;
-      }
-      if (multiplier != 1) {
-        str = str.substring(0, str.length()-2);
-      }
-      
-      quota = Long.parseLong(str);
-      if (quota > Long.MAX_VALUE/multiplier) {
-        throw new IllegalArgumentException("quota exceeds Long.MAX_VALUE!");
-      }
-      quota *= multiplier;
+      quota = StringUtils.TraditionalBinaryPrefix.string2long(str);
       this.args = parameters.toArray(new String[parameters.size()]);
     }
     

+ 8 - 4
src/test/org/apache/hadoop/hdfs/TestQuota.java

@@ -75,6 +75,10 @@ public class TestQuota extends TestCase {
       String[] args = new String[]{"-setQuota", "3", parent.toString()};
       runCommand(admin, args, false);
 
+      //try setting space quota with a 'binary prefix'
+      runCommand(admin, false, "-setSpaceQuota", "2t", parent.toString());
+      assertEquals(2L<<40, dfs.getContentSummary(parent).getSpaceQuota());
+      
       // set diskspace quota to 10000 
       runCommand(admin, false, "-setSpaceQuota", 
                  Long.toString(spaceQuota), parent.toString());
@@ -188,7 +192,7 @@ public class TestQuota extends TestCase {
       assertFalse(dfs.exists(nonExistentPath));
       args = new String[]{"-setQuota", "1", nonExistentPath.toString()};
       runCommand(admin, args, true);
-      runCommand(admin, true, "-setSpaceQuota", "1GB", // for space quota
+      runCommand(admin, true, "-setSpaceQuota", "1g", // for space quota
                  nonExistentPath.toString());
       
       // 14b: set quota on a file
@@ -196,7 +200,7 @@ public class TestQuota extends TestCase {
       args[1] = childFile0.toString();
       runCommand(admin, args, true);
       // same for space quota
-      runCommand(admin, true, "-setSpaceQuota", "1GB", args[1]);
+      runCommand(admin, true, "-setSpaceQuota", "1t", args[1]);
       
       // 15a: clear quota on a file
       args[0] = "-clrQuota";
@@ -230,7 +234,7 @@ public class TestQuota extends TestCase {
       
       // 16e: set space quota with a value larger than Long.MAX_VALUE
       runCommand(admin, true, "-setSpaceQuota", 
-                 (Long.MAX_VALUE/1024/1024 + 1024) + "TB", args[2]);
+                 (Long.MAX_VALUE/1024/1024 + 1024) + "m", args[2]);
       
       // 17:  setQuota by a non-administrator
       UnixUserGroupInformation.saveToConf(conf, 
@@ -239,7 +243,7 @@ public class TestQuota extends TestCase {
       DFSAdmin userAdmin = new DFSAdmin(conf);
       args[1] = "100";
       runCommand(userAdmin, args, true);
-      runCommand(userAdmin, true, "-setSpaceQuota", "1GB", args[2]);
+      runCommand(userAdmin, true, "-setSpaceQuota", "1g", args[2]);
       
       // 18: clrQuota by a non-administrator
       args = new String[] {"-clrQuota", parent.toString()};