|
@@ -19,6 +19,7 @@
|
|
package org.apache.hadoop.ozone.container.common.volume;
|
|
package org.apache.hadoop.ozone.container.common.volume;
|
|
|
|
|
|
import com.google.common.annotations.VisibleForTesting;
|
|
import com.google.common.annotations.VisibleForTesting;
|
|
|
|
+import edu.umd.cs.findbugs.annotations.SuppressFBWarnings;
|
|
import org.apache.hadoop.conf.Configuration;
|
|
import org.apache.hadoop.conf.Configuration;
|
|
import org.apache.hadoop.fs.CachingGetSpaceUsed;
|
|
import org.apache.hadoop.fs.CachingGetSpaceUsed;
|
|
import org.apache.hadoop.fs.DF;
|
|
import org.apache.hadoop.fs.DF;
|
|
@@ -35,6 +36,7 @@ import java.io.IOException;
|
|
import java.io.OutputStreamWriter;
|
|
import java.io.OutputStreamWriter;
|
|
import java.nio.charset.StandardCharsets;
|
|
import java.nio.charset.StandardCharsets;
|
|
import java.util.Scanner;
|
|
import java.util.Scanner;
|
|
|
|
+import java.util.concurrent.atomic.AtomicReference;
|
|
|
|
|
|
/**
|
|
/**
|
|
* Class that wraps the space df of the Datanode Volumes used by SCM
|
|
* Class that wraps the space df of the Datanode Volumes used by SCM
|
|
@@ -46,7 +48,8 @@ public class VolumeUsage {
|
|
private final File rootDir;
|
|
private final File rootDir;
|
|
private final DF df;
|
|
private final DF df;
|
|
private final File scmUsedFile;
|
|
private final File scmUsedFile;
|
|
- private GetSpaceUsed scmUsage;
|
|
|
|
|
|
+ private AtomicReference<GetSpaceUsed> scmUsage;
|
|
|
|
+ private boolean shutdownComplete;
|
|
|
|
|
|
private static final String DU_CACHE_FILE = "scmUsed";
|
|
private static final String DU_CACHE_FILE = "scmUsed";
|
|
private volatile boolean scmUsedSaved = false;
|
|
private volatile boolean scmUsedSaved = false;
|
|
@@ -65,10 +68,11 @@ public class VolumeUsage {
|
|
|
|
|
|
void startScmUsageThread(Configuration conf) throws IOException {
|
|
void startScmUsageThread(Configuration conf) throws IOException {
|
|
// get SCM specific df
|
|
// get SCM specific df
|
|
- this.scmUsage = new CachingGetSpaceUsed.Builder().setPath(rootDir)
|
|
|
|
- .setConf(conf)
|
|
|
|
- .setInitialUsed(loadScmUsed())
|
|
|
|
- .build();
|
|
|
|
|
|
+ scmUsage = new AtomicReference<>(
|
|
|
|
+ new CachingGetSpaceUsed.Builder().setPath(rootDir)
|
|
|
|
+ .setConf(conf)
|
|
|
|
+ .setInitialUsed(loadScmUsed())
|
|
|
|
+ .build());
|
|
}
|
|
}
|
|
|
|
|
|
long getCapacity() {
|
|
long getCapacity() {
|
|
@@ -89,14 +93,18 @@ public class VolumeUsage {
|
|
}
|
|
}
|
|
|
|
|
|
long getScmUsed() throws IOException{
|
|
long getScmUsed() throws IOException{
|
|
- return scmUsage.getUsed();
|
|
|
|
|
|
+ return scmUsage.get().getUsed();
|
|
}
|
|
}
|
|
|
|
|
|
- public void shutdown() {
|
|
|
|
- saveScmUsed();
|
|
|
|
|
|
+ public synchronized void shutdown() {
|
|
|
|
+ if (!shutdownComplete) {
|
|
|
|
+ saveScmUsed();
|
|
|
|
|
|
- if (scmUsage instanceof CachingGetSpaceUsed) {
|
|
|
|
- IOUtils.cleanupWithLogger(null, ((CachingGetSpaceUsed) scmUsage));
|
|
|
|
|
|
+ if (scmUsage.get() instanceof CachingGetSpaceUsed) {
|
|
|
|
+ IOUtils.cleanupWithLogger(
|
|
|
|
+ null, ((CachingGetSpaceUsed) scmUsage.get()));
|
|
|
|
+ }
|
|
|
|
+ shutdownComplete = true;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
|
|
@@ -175,7 +183,11 @@ public class VolumeUsage {
|
|
* Only for testing. Do not use otherwise.
|
|
* Only for testing. Do not use otherwise.
|
|
*/
|
|
*/
|
|
@VisibleForTesting
|
|
@VisibleForTesting
|
|
|
|
+ @SuppressFBWarnings(
|
|
|
|
+ value = "IS2_INCONSISTENT_SYNC",
|
|
|
|
+ justification = "scmUsage is an AtomicReference. No additional " +
|
|
|
|
+ "synchronization is needed.")
|
|
public void setScmUsageForTesting(GetSpaceUsed scmUsageForTest) {
|
|
public void setScmUsageForTesting(GetSpaceUsed scmUsageForTest) {
|
|
- this.scmUsage = scmUsageForTest;
|
|
|
|
|
|
+ scmUsage.set(scmUsageForTest);
|
|
}
|
|
}
|
|
}
|
|
}
|