|
@@ -206,6 +206,7 @@ public class NameNode {
|
|
|
private final boolean haEnabled;
|
|
|
private final HAContext haContext;
|
|
|
protected boolean allowStaleStandbyReads;
|
|
|
+ private Runtime runtime = Runtime.getRuntime();
|
|
|
|
|
|
|
|
|
/** httpServer */
|
|
@@ -481,11 +482,16 @@ public class NameNode {
|
|
|
}
|
|
|
|
|
|
private void startTrashEmptier(Configuration conf) throws IOException {
|
|
|
- long trashInterval
|
|
|
- = conf.getLong(CommonConfigurationKeys.FS_TRASH_INTERVAL_KEY,
|
|
|
- CommonConfigurationKeys.FS_TRASH_INTERVAL_DEFAULT);
|
|
|
- if(trashInterval == 0)
|
|
|
+ long trashInterval = conf.getLong(
|
|
|
+ CommonConfigurationKeys.FS_TRASH_INTERVAL_KEY,
|
|
|
+ CommonConfigurationKeys.FS_TRASH_INTERVAL_DEFAULT);
|
|
|
+ if (trashInterval == 0) {
|
|
|
return;
|
|
|
+ } else if (trashInterval < 0) {
|
|
|
+ throw new IOException("Cannot start tresh emptier with negative interval."
|
|
|
+ + " Set " + CommonConfigurationKeys.FS_TRASH_INTERVAL_KEY + " to a"
|
|
|
+ + " positive value.");
|
|
|
+ }
|
|
|
this.emptier = new Thread(new Trash(conf).getEmptier(), "Trash Emptier");
|
|
|
this.emptier.setDaemon(true);
|
|
|
this.emptier.start();
|
|
@@ -1235,14 +1241,37 @@ public class NameNode {
|
|
|
}
|
|
|
return state.getServiceState();
|
|
|
}
|
|
|
+
|
|
|
+ @VisibleForTesting
|
|
|
+ public synchronized void setRuntimeForTesting(Runtime runtime) {
|
|
|
+ this.runtime = runtime;
|
|
|
+ }
|
|
|
|
|
|
/**
|
|
|
- * Class used as expose {@link NameNode} as context to {@link HAState}
|
|
|
+ * Shutdown the NN immediately in an ungraceful way. Used when it would be
|
|
|
+ * unsafe for the NN to continue operating, e.g. during a failed HA state
|
|
|
+ * transition.
|
|
|
*
|
|
|
- * TODO(HA):
|
|
|
- * When entering and exiting state, on failing to start services,
|
|
|
- * appropriate action is needed todo either shutdown the node or recover
|
|
|
- * from failure.
|
|
|
+ * @param t exception which warrants the shutdown. Printed to the NN log
|
|
|
+ * before exit.
|
|
|
+ * @throws ServiceFailedException thrown only for testing.
|
|
|
+ */
|
|
|
+ private synchronized void doImmediateShutdown(Throwable t)
|
|
|
+ throws ServiceFailedException {
|
|
|
+ String message = "Error encountered requiring NN shutdown. " +
|
|
|
+ "Shutting down immediately.";
|
|
|
+ try {
|
|
|
+ LOG.fatal(message, t);
|
|
|
+ } catch (Throwable ignored) {
|
|
|
+ // This is unlikely to happen, but there's nothing we can do if it does.
|
|
|
+ }
|
|
|
+ runtime.exit(1);
|
|
|
+ // This code is only reached during testing, when runtime is stubbed out.
|
|
|
+ throw new ServiceFailedException(message, t);
|
|
|
+ }
|
|
|
+
|
|
|
+ /**
|
|
|
+ * Class used to expose {@link NameNode} as context to {@link HAState}
|
|
|
*/
|
|
|
protected class NameNodeHAContext implements HAContext {
|
|
|
@Override
|
|
@@ -1257,32 +1286,52 @@ public class NameNode {
|
|
|
|
|
|
@Override
|
|
|
public void startActiveServices() throws IOException {
|
|
|
- namesystem.startActiveServices();
|
|
|
- startTrashEmptier(conf);
|
|
|
+ try {
|
|
|
+ namesystem.startActiveServices();
|
|
|
+ startTrashEmptier(conf);
|
|
|
+ } catch (Throwable t) {
|
|
|
+ doImmediateShutdown(t);
|
|
|
+ }
|
|
|
}
|
|
|
|
|
|
@Override
|
|
|
public void stopActiveServices() throws IOException {
|
|
|
- if (namesystem != null) {
|
|
|
- namesystem.stopActiveServices();
|
|
|
+ try {
|
|
|
+ if (namesystem != null) {
|
|
|
+ namesystem.stopActiveServices();
|
|
|
+ }
|
|
|
+ stopTrashEmptier();
|
|
|
+ } catch (Throwable t) {
|
|
|
+ doImmediateShutdown(t);
|
|
|
}
|
|
|
- stopTrashEmptier();
|
|
|
}
|
|
|
|
|
|
@Override
|
|
|
public void startStandbyServices() throws IOException {
|
|
|
- namesystem.startStandbyServices(conf);
|
|
|
+ try {
|
|
|
+ namesystem.startStandbyServices(conf);
|
|
|
+ } catch (Throwable t) {
|
|
|
+ doImmediateShutdown(t);
|
|
|
+ }
|
|
|
}
|
|
|
|
|
|
@Override
|
|
|
public void prepareToStopStandbyServices() throws ServiceFailedException {
|
|
|
- namesystem.prepareToStopStandbyServices();
|
|
|
+ try {
|
|
|
+ namesystem.prepareToStopStandbyServices();
|
|
|
+ } catch (Throwable t) {
|
|
|
+ doImmediateShutdown(t);
|
|
|
+ }
|
|
|
}
|
|
|
|
|
|
@Override
|
|
|
public void stopStandbyServices() throws IOException {
|
|
|
- if (namesystem != null) {
|
|
|
- namesystem.stopStandbyServices();
|
|
|
+ try {
|
|
|
+ if (namesystem != null) {
|
|
|
+ namesystem.stopStandbyServices();
|
|
|
+ }
|
|
|
+ } catch (Throwable t) {
|
|
|
+ doImmediateShutdown(t);
|
|
|
}
|
|
|
}
|
|
|
|