Browse Source

HDDS-1559. Include committedBytes to determine Out of Space in VolumeChoosingPolicy. Contributed by Supratim Deka (#841)

supratimdeka 6 years ago
parent
commit
346c2b7980

+ 3 - 1
hadoop-hdds/container-service/src/main/java/org/apache/hadoop/ozone/container/common/volume/RoundRobinVolumeChoosingPolicy.java

@@ -58,7 +58,9 @@ public class RoundRobinVolumeChoosingPolicy implements VolumeChoosingPolicy {
 
 
     while (true) {
     while (true) {
       final HddsVolume volume = volumes.get(currentVolumeIndex);
       final HddsVolume volume = volumes.get(currentVolumeIndex);
-      long availableVolumeSize = volume.getAvailable();
+      // adjust for remaining capacity in Open containers
+      long availableVolumeSize = volume.getAvailable()
+          - volume.getCommittedBytes();
 
 
       currentVolumeIndex = (currentVolumeIndex + 1) % volumes.size();
       currentVolumeIndex = (currentVolumeIndex + 1) % volumes.size();
 
 

+ 35 - 0
hadoop-hdds/container-service/src/test/java/org/apache/hadoop/ozone/container/ozoneimpl/TestOzoneContainer.java

@@ -28,6 +28,7 @@ import org.apache.hadoop.hdds.conf.OzoneConfiguration;
 import org.apache.hadoop.hdds.protocol.DatanodeDetails;
 import org.apache.hadoop.hdds.protocol.DatanodeDetails;
 import org.apache.hadoop.hdds.protocol.datanode.proto.ContainerProtos;
 import org.apache.hadoop.hdds.protocol.datanode.proto.ContainerProtos;
 import org.apache.hadoop.hdds.scm.ScmConfigKeys;
 import org.apache.hadoop.hdds.scm.ScmConfigKeys;
+import org.apache.hadoop.hdds.scm.container.common.helpers.StorageContainerException;
 import org.apache.hadoop.ozone.container.common.helpers.BlockData;
 import org.apache.hadoop.ozone.container.common.helpers.BlockData;
 import org.apache.hadoop.ozone.container.common.helpers.ChunkInfo;
 import org.apache.hadoop.ozone.container.common.helpers.ChunkInfo;
 import org.apache.hadoop.ozone.container.common.impl.ContainerSet;
 import org.apache.hadoop.ozone.container.common.impl.ContainerSet;
@@ -52,6 +53,7 @@ import java.util.HashMap;
 import java.util.List;
 import java.util.List;
 import java.util.ArrayList;
 import java.util.ArrayList;
 
 
+import static org.apache.hadoop.hdds.protocol.datanode.proto.ContainerProtos.Result.DISK_OUT_OF_SPACE;
 import static org.junit.Assert.assertEquals;
 import static org.junit.Assert.assertEquals;
 
 
 /**
 /**
@@ -135,6 +137,39 @@ public class TestOzoneContainer {
     verifyCommittedSpace(ozoneContainer);
     verifyCommittedSpace(ozoneContainer);
   }
   }
 
 
+  @Test
+  public void testContainerCreateDiskFull() throws Exception {
+    volumeSet = new VolumeSet(datanodeDetails.getUuidString(), conf);
+    volumeChoosingPolicy = new RoundRobinVolumeChoosingPolicy();
+    long containerSize = (long) StorageUnit.MB.toBytes(100);
+    boolean diskSpaceException = false;
+
+    // Format the volumes
+    for (HddsVolume volume : volumeSet.getVolumesList()) {
+      volume.format(UUID.randomUUID().toString());
+
+      // eat up all available space except size of 1 container
+      volume.incCommittedBytes(volume.getAvailable() - containerSize);
+      // eat up 10 bytes more, now available space is less than 1 container
+      volume.incCommittedBytes(10);
+    }
+    keyValueContainerData = new KeyValueContainerData(99, containerSize,
+        UUID.randomUUID().toString(), datanodeDetails.getUuidString());
+    keyValueContainer = new KeyValueContainer(keyValueContainerData, conf);
+
+    // we expect an out of space Exception
+    try {
+      keyValueContainer.create(volumeSet, volumeChoosingPolicy, scmId);
+    } catch (StorageContainerException e) {
+      if (e.getResult() == DISK_OUT_OF_SPACE) {
+        diskSpaceException = true;
+      }
+    }
+
+    // Test failed if there was no exception
+    assertEquals(true, diskSpaceException);
+  }
+
   //verify committed space on each volume
   //verify committed space on each volume
   private void verifyCommittedSpace(OzoneContainer oc) {
   private void verifyCommittedSpace(OzoneContainer oc) {
     for (HddsVolume dnVol : oc.getVolumeSet().getVolumesList()) {
     for (HddsVolume dnVol : oc.getVolumeSet().getVolumesList()) {