|
@@ -124,7 +124,12 @@ import org.apache.hadoop.hdfs.server.common.ECTopologyVerifier;
|
|
|
import org.apache.hadoop.hdfs.server.namenode.metrics.ReplicatedBlocksMBean;
|
|
|
import org.apache.hadoop.hdfs.server.protocol.SlowDiskReports;
|
|
|
import org.apache.hadoop.ipc.ObserverRetryOnActiveException;
|
|
|
-import org.apache.hadoop.util.*;
|
|
|
+import org.apache.hadoop.util.Time;
|
|
|
+import org.apache.hadoop.util.Daemon;
|
|
|
+import org.apache.hadoop.util.DataChecksum;
|
|
|
+import org.apache.hadoop.util.ReflectionUtils;
|
|
|
+import org.apache.hadoop.util.StringUtils;
|
|
|
+import org.apache.hadoop.util.VersionInfo;
|
|
|
|
|
|
import static org.apache.hadoop.util.Time.now;
|
|
|
import static org.apache.hadoop.util.Time.monotonicNow;
|
|
@@ -8560,25 +8565,36 @@ public class FSNamesystem implements Namesystem, FSNamesystemMBean,
|
|
|
/**
|
|
|
* Check if snapshot roots are created for all existing snapshottable
|
|
|
* directories. Create them if not.
|
|
|
+ * Only the active NameNode needs to execute this in HA setup once it is out
|
|
|
+ * of safe mode.
|
|
|
+ *
|
|
|
+ * The function gets called while exiting safe mode or post starting the
|
|
|
+ * services in Active NameNode, but comes into effect post whichever event
|
|
|
+ * happens later.
|
|
|
*/
|
|
|
@Override
|
|
|
- public void checkAndProvisionSnapshotTrashRoots() {
|
|
|
- if (isSnapshotTrashRootEnabled) {
|
|
|
+ public synchronized void checkAndProvisionSnapshotTrashRoots() {
|
|
|
+ if (isSnapshotTrashRootEnabled && (haEnabled && inActiveState()
|
|
|
+ || !haEnabled) && !blockManager.isInSafeMode()) {
|
|
|
+ SnapshottableDirectoryStatus dirStatus = null;
|
|
|
try {
|
|
|
SnapshottableDirectoryStatus[] dirStatusList =
|
|
|
getSnapshottableDirListing();
|
|
|
if (dirStatusList == null) {
|
|
|
return;
|
|
|
}
|
|
|
- for (SnapshottableDirectoryStatus dirStatus : dirStatusList) {
|
|
|
+ for (SnapshottableDirectoryStatus status : dirStatusList) {
|
|
|
+ dirStatus = status;
|
|
|
String currDir = dirStatus.getFullPath().toString();
|
|
|
if (!currDir.endsWith(Path.SEPARATOR)) {
|
|
|
currDir += Path.SEPARATOR;
|
|
|
}
|
|
|
String trashPath = currDir + FileSystem.TRASH_PREFIX;
|
|
|
- HdfsFileStatus fileStatus = getFileInfo(trashPath, false, false, false);
|
|
|
+ HdfsFileStatus fileStatus =
|
|
|
+ getFileInfo(trashPath, false, false, false);
|
|
|
if (fileStatus == null) {
|
|
|
- LOG.info("Trash doesn't exist for snapshottable directory {}. " + "Creating trash at {}", currDir, trashPath);
|
|
|
+ LOG.info("Trash doesn't exist for snapshottable directory {}. "
|
|
|
+ + "Creating trash at {}", currDir, trashPath);
|
|
|
PermissionStatus permissionStatus =
|
|
|
new PermissionStatus(getRemoteUser().getShortUserName(), null,
|
|
|
SHARED_TRASH_PERMISSION);
|
|
@@ -8586,12 +8602,13 @@ public class FSNamesystem implements Namesystem, FSNamesystemMBean,
|
|
|
}
|
|
|
}
|
|
|
} catch (IOException e) {
|
|
|
- final String msg =
|
|
|
- "Could not provision Trash directory for existing "
|
|
|
- + "snapshottable directories. Exiting Namenode.";
|
|
|
- ExitUtil.terminate(1, msg);
|
|
|
+ if (dirStatus == null) {
|
|
|
+ LOG.error("Failed to get snapshottable directory list", e);
|
|
|
+ } else {
|
|
|
+ LOG.error("Could not provision Trash directory for existing "
|
|
|
+ + "snapshottable directory {}", dirStatus, e);
|
|
|
+ }
|
|
|
}
|
|
|
-
|
|
|
}
|
|
|
}
|
|
|
|