hadoop-common-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From s..@apache.org
Subject svn commit: r728205 - in /hadoop/core/branches/branch-0.20: CHANGES.txt src/hdfs/org/apache/hadoop/hdfs/server/namenode/FSNamesystem.java src/test/org/apache/hadoop/hdfs/TestSafeMode.java
Date Sat, 20 Dec 2008 01:01:50 GMT
Author: shv
Date: Fri Dec 19 17:01:49 2008
New Revision: 728205

URL: http://svn.apache.org/viewvc?rev=728205&view=rev
Log:
HADOOP-1980. Merge -r 728194:728195 from trunk to branch 0.20.

Added:
    hadoop/core/branches/branch-0.20/src/test/org/apache/hadoop/hdfs/TestSafeMode.java
Modified:
    hadoop/core/branches/branch-0.20/CHANGES.txt
    hadoop/core/branches/branch-0.20/src/hdfs/org/apache/hadoop/hdfs/server/namenode/FSNamesystem.java

Modified: hadoop/core/branches/branch-0.20/CHANGES.txt
URL: http://svn.apache.org/viewvc/hadoop/core/branches/branch-0.20/CHANGES.txt?rev=728205&r1=728204&r2=728205&view=diff
==============================================================================
--- hadoop/core/branches/branch-0.20/CHANGES.txt (original)
+++ hadoop/core/branches/branch-0.20/CHANGES.txt Fri Dec 19 17:01:49 2008
@@ -1574,6 +1574,9 @@
 
     HADOOP-4904. Fix deadlock while leaving safe mode. (shv)
 
+    HADOOP-1980. 'dfsadmin -safemode enter' should prevent the namenode from
+    leaving safemode automatically. (shv)
+
 Release 0.18.2 - 2008-11-03
 
   BUG FIXES

Modified: hadoop/core/branches/branch-0.20/src/hdfs/org/apache/hadoop/hdfs/server/namenode/FSNamesystem.java
URL: http://svn.apache.org/viewvc/hadoop/core/branches/branch-0.20/src/hdfs/org/apache/hadoop/hdfs/server/namenode/FSNamesystem.java?rev=728205&r1=728204&r2=728205&view=diff
==============================================================================
--- hadoop/core/branches/branch-0.20/src/hdfs/org/apache/hadoop/hdfs/server/namenode/FSNamesystem.java
(original)
+++ hadoop/core/branches/branch-0.20/src/hdfs/org/apache/hadoop/hdfs/server/namenode/FSNamesystem.java
Fri Dec 19 17:01:49 2008
@@ -3811,6 +3811,8 @@
     /** time of the last status printout */
     private long lastStatusReport = 0;
       
+    private boolean isManual = false;
+    
     /**
      * Creates SafeModeInfo when the name node enters
      * automatic safe mode at startup.
@@ -3840,6 +3842,7 @@
       this.blockTotal = -1;
       this.blockSafe = -1;
       this.reached = -1;
+      this.isManual = true;
       enter();
       reportStatus("STATE* Safe mode is ON.", true);
     }
@@ -3898,6 +3901,7 @@
         NameNode.stateChangeLog.info("STATE* Safe mode is OFF."); 
       }
       reached = -1;
+      unsetManual();
       safeMode = null;
       NameNode.stateChangeLog.info("STATE* Network topology has "
                                    +clusterMap.getNumOfRacks()+" racks and "
@@ -3915,7 +3919,7 @@
     synchronized boolean canLeave() {
       if (reached == 0)
         return false;
-      if (now() - reached < extension) {
+      if (now() - reached < extension || isManual()) {
         reportStatus("STATE* Safe mode ON.", false);
         return false;
       }
@@ -3935,14 +3939,14 @@
      * to be compared with the threshold.
      */
     private float getSafeBlockRatio() {
-      return (blockTotal == 0 ? 1 : (float)blockSafe/blockTotal);
+      return (blockTotal <= 0 ? 1 : (float)blockSafe/blockTotal);
     }
       
     /**
      * Check and trigger safe mode if needed. 
      */
     private void checkMode() {
-      if (needEnter()) {
+      if (isManual() || needEnter()) {
         enter();
         reportStatus("STATE* Safe mode ON.", false);
         return;
@@ -3997,10 +4001,18 @@
     /**
      * Check if safe mode was entered manually or at startup.
      */
-    boolean isManual() {
-      return blockTotal == -1;
+    private boolean isManual() {
+      return isManual;
     }
       
+    private synchronized void setManual() {
+      isManual = true;
+    }
+
+    private synchronized void unsetManual() {
+      isManual = false;
+    }
+    
     /**
      * A tip on how safe mode is to be turned off: manually or automatically.
      */
@@ -4008,17 +4020,23 @@
       final String autoOffMsg = "Safe mode will be turned off automatically";
       if(reached < 0)
         return "Safe mode is OFF.";
+      float ratio = getSafeBlockRatio();
+      String safeBlockRatioMsg = 
+        String.format("The ratio of reported blocks %.4f has " +
+          (ratio < threshold ? "not " : "") + "reached the threshold %.4f. ",
+          ratio, threshold);
+      
       if(isManual()) {
         if(getDistributedUpgradeState())
           return autoOffMsg + " upon completion of " + 
             "the distributed upgrade: upgrade progress = " + 
             getDistributedUpgradeStatus() + "%";
-        return "Use \"hadoop dfs -safemode leave\" to turn safe mode off.";
+        // add block ratio message if it is relevant
+        return ((blockTotal >= 0) ? safeBlockRatioMsg : "") + 
+               "Use \"hadoop dfs -safemode leave\" to turn safe mode off.";             
       }
-      String safeBlockRatioMsg = 
-        String.format("The ratio of reported blocks %.4f has " +
-          (reached == 0 ? "not " : "") + "reached the threshold %.4f. ",
-          getSafeBlockRatio(), threshold) + autoOffMsg;
+
+      safeBlockRatioMsg += autoOffMsg;
       if(reached == 0)  // threshold is not reached 
         return safeBlockRatioMsg + ".";
       // extension period is in progress
@@ -4172,6 +4190,7 @@
    */
   synchronized void enterSafeMode() throws IOException {
     if (isInSafeMode()) {
+      safeMode.setManual();
       NameNode.stateChangeLog.info("STATE* Safe mode is already ON."); 
       return;
     }
@@ -4190,6 +4209,7 @@
     if(getDistributedUpgradeState())
       throw new SafeModeException("Distributed upgrade is in progress",
                                   safeMode);
+    safeMode.unsetManual();
     safeMode.leave(checkForUpgrades);
   }
     

Added: hadoop/core/branches/branch-0.20/src/test/org/apache/hadoop/hdfs/TestSafeMode.java
URL: http://svn.apache.org/viewvc/hadoop/core/branches/branch-0.20/src/test/org/apache/hadoop/hdfs/TestSafeMode.java?rev=728205&view=auto
==============================================================================
--- hadoop/core/branches/branch-0.20/src/test/org/apache/hadoop/hdfs/TestSafeMode.java (added)
+++ hadoop/core/branches/branch-0.20/src/test/org/apache/hadoop/hdfs/TestSafeMode.java Fri
Dec 19 17:01:49 2008
@@ -0,0 +1,95 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.hadoop.hdfs;
+
+import java.io.IOException;
+
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+import org.apache.hadoop.conf.Configuration;
+import org.apache.hadoop.fs.FileSystem;
+import org.apache.hadoop.fs.Path;
+import org.apache.hadoop.hdfs.protocol.FSConstants.SafeModeAction;
+import org.apache.hadoop.hdfs.server.namenode.NameNode;
+
+import junit.framework.TestCase;
+
+/**
+ * This test makes sure that if SafeMode is manually entered, NameNode does not
+ * come out of safe mode even after the startup safemode conditions are met.
+ */
+public class TestSafeMode extends TestCase {
+  
+  static Log LOG = LogFactory.getLog(TestSafeMode.class);
+  
+  public void testManualSafeMode() throws IOException {
+    MiniDFSCluster cluster = null;
+    FileSystem fs = null;
+    try {
+      Configuration conf = new Configuration();
+      // disable safemode extension to make the test run faster.
+      conf.set("dfs.safemode.extension", "1");
+      cluster = new MiniDFSCluster(conf, 1, true, null);
+      cluster.waitActive();
+      
+      fs = cluster.getFileSystem();
+      Path file1 = new Path("/tmp/testManualSafeMode/file1");
+      Path file2 = new Path("/tmp/testManualSafeMode/file2");
+      
+      LOG.info("Created file1 and file2.");
+      
+      // create two files with one block each.
+      DFSTestUtil.createFile(fs, file1, 1000, (short)1, 0);
+      DFSTestUtil.createFile(fs, file2, 2000, (short)1, 0);    
+      cluster.shutdown();
+      
+      // now bring up just the NameNode.
+      cluster = new MiniDFSCluster(conf, 0, false, null);
+      cluster.waitActive();
+      
+      LOG.info("Restarted cluster with just the NameNode");
+      
+      NameNode namenode = cluster.getNameNode();
+      
+      assertTrue("No datanode is started. Should be in SafeMode", 
+                 namenode.isInSafeMode());
+      
+      // manually set safemode.
+      namenode.setSafeMode(SafeModeAction.SAFEMODE_ENTER);
+      
+      // now bring up the datanode and wait for it to be active.
+      cluster.startDataNodes(conf, 1, true, null, null);
+      cluster.waitActive();
+      
+      LOG.info("Datanode is started.");
+      
+      try {
+        Thread.sleep(2000);
+      } catch (InterruptedException ignored) {}
+      
+      assertTrue("should still be in SafeMode", namenode.isInSafeMode());
+      
+      namenode.setSafeMode(SafeModeAction.SAFEMODE_LEAVE);
+      assertFalse("should not be in SafeMode", namenode.isInSafeMode());
+    } finally {
+      if(fs != null) fs.close();
+      if(cluster!= null) cluster.shutdown();
+    }
+  }
+}



Mime
View raw message