Index: hbase-server/src/main/java/org/apache/hadoop/hbase/TableInfoMissingException.java =================================================================== --- hbase-server/src/main/java/org/apache/hadoop/hbase/TableInfoMissingException.java (revision 0) +++ hbase-server/src/main/java/org/apache/hadoop/hbase/TableInfoMissingException.java (working copy) @@ -0,0 +1,30 @@ +package org.apache.hadoop.hbase; + +import org.apache.hadoop.classification.InterfaceAudience; + +/** + * + * Failed to find .tableinfo file under table dir + * + */ +@InterfaceAudience.Private +@SuppressWarnings("serial") +public class TableInfoMissingException extends HBaseIOException { + + public TableInfoMissingException() { + super(); + } + + public TableInfoMissingException( String message ) { + super(message); + } + + public TableInfoMissingException( String message, Throwable t ) { + super(message, t); + } + + public TableInfoMissingException( Throwable t ) { + super(t); + } + +} Index: hbase-server/src/main/java/org/apache/hadoop/hbase/util/FSTableDescriptors.java =================================================================== --- hbase-server/src/main/java/org/apache/hadoop/hbase/util/FSTableDescriptors.java (revision 1378921) +++ hbase-server/src/main/java/org/apache/hadoop/hbase/util/FSTableDescriptors.java (working copy) @@ -43,6 +43,7 @@ import org.apache.hadoop.hbase.HConstants; import org.apache.hadoop.hbase.HTableDescriptor; import org.apache.hadoop.hbase.TableDescriptors; +import org.apache.hadoop.hbase.TableInfoMissingException; import org.apache.hadoop.hbase.protobuf.ProtobufUtil; import com.google.common.primitives.Ints; @@ -163,7 +164,18 @@ return tdm.getTableDescriptor(); } } - HTableDescriptor htd = getTableDescriptor(this.fs, this.rootdir, tablename); + + HTableDescriptor htd = null; + try { + htd = getTableDescriptor(this.fs, this.rootdir, tablename); + } catch (NullPointerException e) { + LOG.debug("Exception during readTableDecriptor. Current table name = " + + tablename, e); + } catch (IOException ioe) { + LOG.debug("Exception during readTableDecriptor. Current table name = " + + tablename, ioe); + } + if (htd == null) { LOG.warn("The following folder is in HBase's root directory and " + "doesn't contain a table descriptor, " + @@ -258,7 +270,7 @@ * @return The 'current' tableinfo file. * @throws IOException */ - private static FileStatus getTableInfoPath(final FileSystem fs, + public static FileStatus getTableInfoPath(final FileSystem fs, final Path tabledir) throws IOException { FileStatus [] status = FSUtils.listStatus(fs, tabledir, new PathFilter() { @@ -375,21 +387,27 @@ public static HTableDescriptor getTableDescriptor(FileSystem fs, Path hbaseRootDir, byte[] tableName) throws IOException { - return getTableDescriptor(fs, hbaseRootDir, Bytes.toString(tableName)); + HTableDescriptor htd = null; + try { + htd = getTableDescriptor(fs, hbaseRootDir, Bytes.toString(tableName)); + } catch (NullPointerException e) { + LOG.debug("Exception during readTableDecriptor. Current table name = " + + Bytes.toString(tableName), e); + } + return htd; } static HTableDescriptor getTableDescriptor(FileSystem fs, - Path hbaseRootDir, String tableName) { + Path hbaseRootDir, String tableName) throws NullPointerException, IOException{ HTableDescriptor htd = null; - try { - htd = getTableDescriptor(fs, FSUtils.getTablePath(hbaseRootDir, tableName)); - } catch (NullPointerException e) { - LOG.debug("Exception during readTableDecriptor. Current table name = " + - tableName , e); - } catch (IOException ioe) { - LOG.debug("Exception during readTableDecriptor. Current table name = " + - tableName , ioe); + // ignore both -ROOT- and .META. tables + if (Bytes.compareTo(Bytes.toBytes(tableName), + HConstants.ROOT_TABLE_NAME) ==0 + || Bytes.compareTo(Bytes.toBytes(tableName), + HConstants.META_TABLE_NAME) == 0) { + return null; } + htd = getTableDescriptor(fs, FSUtils.getTablePath(hbaseRootDir, tableName)); return htd; } @@ -397,7 +415,7 @@ throws IOException, NullPointerException { if (tableDir == null) throw new NullPointerException(); FileStatus status = getTableInfoPath(fs, tableDir); - if (status == null) return null; + if (status == null) throw new TableInfoMissingException("NO .tableinfo file under " +tableDir.toUri()); int len = Ints.checkedCast(status.getLen()); byte [] content = new byte[len]; FSDataInputStream fsDataInputStream = fs.open(status.getPath()); Index: hbase-server/src/main/java/org/apache/hadoop/hbase/util/HBaseFsck.java =================================================================== --- hbase-server/src/main/java/org/apache/hadoop/hbase/util/HBaseFsck.java (revision 1378921) +++ hbase-server/src/main/java/org/apache/hadoop/hbase/util/HBaseFsck.java (working copy) @@ -714,6 +714,9 @@ } catch (IOException ioe) { LOG.error("Unable to read .tableinfo from " + hbaseRoot, ioe); throw ioe; + } catch (NullPointerException npe) { + LOG.error("Unable to read .tableinfo from " + hbaseRoot, npe); + throw npe; } } modTInfo.addRegionInfo(hbi); Index: hbase-server/src/test/java/org/apache/hadoop/hbase/util/TestFSTableDescriptors.java =================================================================== --- hbase-server/src/test/java/org/apache/hadoop/hbase/util/TestFSTableDescriptors.java (revision 1378921) +++ hbase-server/src/test/java/org/apache/hadoop/hbase/util/TestFSTableDescriptors.java (working copy) @@ -136,7 +136,7 @@ assertNull(htds.remove(htd.getNameAsString())); } - @Test public void testReadingHTDFromFS() throws IOException { + @Test public void testReadingHTDFromFS() throws IOException, NullPointerException{ final String name = "testReadingHTDFromFS"; FileSystem fs = FileSystem.get(UTIL.getConfiguration()); HTableDescriptor htd = new HTableDescriptor(name); Index: hbase-server/src/test/java/org/apache/hadoop/hbase/util/TestHBaseFsck.java =================================================================== --- hbase-server/src/test/java/org/apache/hadoop/hbase/util/TestHBaseFsck.java (revision 1378921) +++ hbase-server/src/test/java/org/apache/hadoop/hbase/util/TestHBaseFsck.java (working copy) @@ -414,6 +414,28 @@ } } + @Test + public void testHbckMissingTableinfo() throws Exception { + String table = "tabeInfo"; + FileSystem fs = null; + Path tableinfo = null; + try { + setupTable(table); + Path hbaseTableDir = new Path(conf.get(HConstants.HBASE_DIR) + "/" + table ); + fs = hbaseTableDir.getFileSystem(conf); + FileStatus status = FSTableDescriptors.getTableInfoPath(fs, hbaseTableDir); + tableinfo = status.getPath(); + fs.rename(tableinfo, new Path("/.tableinfo")); + + doFsck(conf, false); + } catch (IOException ioe) { + assertNotNull("No IOException found while .tableinfo missing", ioe); + } finally { + fs.rename(new Path("/.tableinfo"), tableinfo); + deleteTable(table); + } + } + /** * This create and fixes a bad table with regions that have a duplicate * start key