diff --git a/hadoop-hdds/container-service/src/main/java/org/apache/hadoop/ozone/container/common/volume/RoundRobinVolumeChoosingPolicy.java b/hadoop-hdds/container-service/src/main/java/org/apache/hadoop/ozone/container/common/volume/RoundRobinVolumeChoosingPolicy.java index 75c92ec024..f503149aca 100644 --- a/hadoop-hdds/container-service/src/main/java/org/apache/hadoop/ozone/container/common/volume/RoundRobinVolumeChoosingPolicy.java +++ b/hadoop-hdds/container-service/src/main/java/org/apache/hadoop/ozone/container/common/volume/RoundRobinVolumeChoosingPolicy.java @@ -58,7 +58,9 @@ public HddsVolume chooseVolume(List volumes, while (true) { 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(); diff --git a/hadoop-hdds/container-service/src/test/java/org/apache/hadoop/ozone/container/ozoneimpl/TestOzoneContainer.java b/hadoop-hdds/container-service/src/test/java/org/apache/hadoop/ozone/container/ozoneimpl/TestOzoneContainer.java index e6782823ed..f5ebb49d06 100644 --- a/hadoop-hdds/container-service/src/test/java/org/apache/hadoop/ozone/container/ozoneimpl/TestOzoneContainer.java +++ b/hadoop-hdds/container-service/src/test/java/org/apache/hadoop/ozone/container/ozoneimpl/TestOzoneContainer.java @@ -28,6 +28,7 @@ import org.apache.hadoop.hdds.protocol.DatanodeDetails; import org.apache.hadoop.hdds.protocol.datanode.proto.ContainerProtos; 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.ChunkInfo; import org.apache.hadoop.ozone.container.common.impl.ContainerSet; @@ -52,6 +53,7 @@ import java.util.List; 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; /** @@ -135,6 +137,39 @@ public void testBuildContainerMap() throws Exception { 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 private void verifyCommittedSpace(OzoneContainer oc) { for (HddsVolume dnVol : oc.getVolumeSet().getVolumesList()) {