Index: hbase/src/main/java/org/apache/hadoop/hbase/master/HMaster.java =================================================================== --- hbase/src/main/java/org/apache/hadoop/hbase/master/HMaster.java (revision 040ed428f6a18a3aa8abc43fc65256bba61c4e93) +++ hbase/src/main/java/org/apache/hadoop/hbase/master/HMaster.java (revision ) @@ -526,11 +526,11 @@ if (!isMetaHRIUpdated()) { LOG.info("Meta has HRI with HTDs. Updating meta now."); try { - MetaEditor.updateMetaWithNewRegionInfo(this); + MetaEditor.migrateRootAndMeta(this); LOG.info("Meta updated with new HRI."); return true; } catch (IOException e) { - throw new RuntimeException("Update Meta with nw HRI failed. Master startup aborted."); + throw new RuntimeException("Update Meta with new HRI failed. Master startup aborted."); } } LOG.info("Meta already up-to date with new HRI."); @@ -975,7 +975,6 @@ return hRegionInfos; } - private static boolean isCatalogTable(final byte [] tableName) { return Bytes.equals(tableName, HConstants.ROOT_TABLE_NAME) || Bytes.equals(tableName, HConstants.META_TABLE_NAME); Index: hbase/src/main/java/org/apache/hadoop/hbase/client/HConnectionManager.java =================================================================== --- hbase/src/main/java/org/apache/hadoop/hbase/client/HConnectionManager.java (revision 040ed428f6a18a3aa8abc43fc65256bba61c4e93) +++ hbase/src/main/java/org/apache/hadoop/hbase/client/HConnectionManager.java (revision ) @@ -914,7 +914,8 @@ // possible we got a region of a different table... if (!Bytes.equals(regionInfo.getTableName(), tableName)) { throw new TableNotFoundException( - "Table '" + Bytes.toString(tableName) + "' was not found."); + "Table '" + Bytes.toString(tableName) + "' was not found, got: " + + Bytes.toString(regionInfo.getTableName()) + "."); } if (regionInfo.isSplit()) { throw new RegionOfflineException("the only available region for" + Index: hbase/src/main/java/org/apache/hadoop/hbase/util/FSTableDescriptors.java =================================================================== --- hbase/src/main/java/org/apache/hadoop/hbase/util/FSTableDescriptors.java (revision 040ed428f6a18a3aa8abc43fc65256bba61c4e93) +++ hbase/src/main/java/org/apache/hadoop/hbase/util/FSTableDescriptors.java (revision ) @@ -31,6 +31,7 @@ import org.apache.hadoop.hbase.HTableDescriptor; import org.apache.hadoop.hbase.TableDescriptors; import org.apache.hadoop.hbase.TableExistsException; +import org.mortbay.log.Log; /** * Implementation of {@link TableDescriptors} that reads descriptors from the @@ -151,7 +152,13 @@ Map htds = new TreeMap(); List tableDirs = FSUtils.getTableDirs(fs, rootdir); for (Path d: tableDirs) { - HTableDescriptor htd = get(d.getName()); + HTableDescriptor htd = null; + try { + htd = get(d.getName()); + } catch (FileNotFoundException fnfe) { + // inability of retrieving one HTD shouldn't stop getting the remaining + Log.warn("Trouble retrieving htd", fnfe); + } if (htd == null) continue; htds.put(d.getName(), htd); } Index: hbase/src/main/java/org/apache/hadoop/hbase/master/MasterFileSystem.java =================================================================== --- hbase/src/main/java/org/apache/hadoop/hbase/master/MasterFileSystem.java (revision 040ed428f6a18a3aa8abc43fc65256bba61c4e93) +++ hbase/src/main/java/org/apache/hadoop/hbase/master/MasterFileSystem.java (revision ) @@ -324,9 +324,18 @@ if (!FSUtils.rootRegionExists(fs, rd)) { bootstrap(rd, c); } + createRootTableInfo(rd); return rd; } + private void createRootTableInfo(Path rd) throws IOException { + // Create ROOT tableInfo if required. + if (!FSUtils.tableInfoExists(fs, rd, + Bytes.toString(HRegionInfo.ROOT_REGIONINFO.getTableName()))) { + FSUtils.createTableDescriptor(HTableDescriptor.ROOT_TABLEDESC, this.conf); + } + } + private static void bootstrap(final Path rd, final Configuration c) throws IOException { LOG.info("BOOTSTRAP: creating ROOT and first META regions"); Index: hbase/src/main/java/org/apache/hadoop/hbase/catalog/MetaReader.java =================================================================== --- hbase/src/main/java/org/apache/hadoop/hbase/catalog/MetaReader.java (revision 040ed428f6a18a3aa8abc43fc65256bba61c4e93) +++ hbase/src/main/java/org/apache/hadoop/hbase/catalog/MetaReader.java (revision ) @@ -622,9 +622,32 @@ return regions; } + /** + * Full scan a given region, on a given server. + * @param hRegionInterface + * @param visitor + * @param regionName + * @throws IOException + */ + public static void fullScan(HRegionInterface hRegionInterface, + Visitor visitor, final byte[] regionName) + throws IOException { + if (hRegionInterface == null) return; + Scan scan = new Scan(); + scan.addFamily(HConstants.CATALOG_FAMILY); + long scannerid = hRegionInterface.openScanner(regionName, scan); + try { + Result data; + while((data = hRegionInterface.next(scannerid)) != null) { + if (!data.isEmpty()) visitor.visit(data); + } + } finally { + hRegionInterface.close(scannerid); + } + return; + } - /** * Implementations 'visit' a catalog table row. */ Index: hbase/src/main/java/org/apache/hadoop/hbase/util/FSUtils.java =================================================================== --- hbase/src/main/java/org/apache/hadoop/hbase/util/FSUtils.java (revision 040ed428f6a18a3aa8abc43fc65256bba61c4e93) +++ hbase/src/main/java/org/apache/hadoop/hbase/util/FSUtils.java (revision ) @@ -490,6 +490,20 @@ return fs.exists(rootRegionDir); } + /** + * Checks if .tableinfo exists for given table + * + * @param fs file system + * @param rootdir root directory of HBase installation + * @param tableName name of table + * @return true if exists + * @throws IOException + */ + public static boolean tableInfoExists(FileSystem fs, Path rootdir, + String tableName) throws IOException { + Path tablePath = getTableInfoPath(rootdir, tableName); + return fs.exists(tablePath); + } /** * Compute HDFS blocks distribution of a given file, or a portion of the file Index: hbase/src/main/java/org/apache/hadoop/hbase/catalog/MetaEditor.java =================================================================== --- hbase/src/main/java/org/apache/hadoop/hbase/catalog/MetaEditor.java (revision 040ed428f6a18a3aa8abc43fc65256bba61c4e93) +++ hbase/src/main/java/org/apache/hadoop/hbase/catalog/MetaEditor.java (revision ) @@ -246,12 +246,13 @@ LOG.info("Updated region " + regionInfo.getRegionNameAsString() + " in META"); } - public static void updateRootWithMetaMigrationStatus(CatalogTracker catalogTracker) throws IOException { + public static void updateRootWithMetaMigrationStatus( + CatalogTracker catalogTracker) throws IOException { updateRootWithMetaMigrationStatus(catalogTracker, true); } - public static void updateRootWithMetaMigrationStatus(CatalogTracker catalogTracker, - boolean metaUpdated) + public static void updateRootWithMetaMigrationStatus( + CatalogTracker catalogTracker, boolean metaUpdated) throws IOException { Put put = new Put(HRegionInfo.ROOT_REGIONINFO.getRegionName()); addMetaUpdateStatus(put, metaUpdated); @@ -289,6 +290,41 @@ return htds; } + public static void migrateRootAndMeta(final MasterServices masterServices) + throws IOException { + updateRootWithNewRegionInfo(masterServices); + updateMetaWithNewRegionInfo(masterServices); + } + + public static List updateRootWithNewRegionInfo( + final MasterServices masterServices) + throws IOException { + final List htds = new ArrayList(); + Visitor v = new Visitor() { + @Override + public boolean visit(Result r) throws IOException { + if (r == null || r.isEmpty()) return true; + HRegionInfo090x hrfm = getHRegionInfoForMigration(r); + if (hrfm == null) return true; + htds.add(hrfm.getTableDesc()); + masterServices.getMasterFileSystem().createTableDescriptor( + hrfm.getTableDesc()); + HRegionInfo regionInfo = new HRegionInfo(hrfm); + Put put = new Put(regionInfo.getRegionName()); + put.add(HConstants.CATALOG_FAMILY, HConstants.REGIONINFO_QUALIFIER, + Writables.getBytes(regionInfo)); + masterServices.getCatalogTracker().waitForRootServerConnectionDefault() + .put(CatalogTracker.ROOT_REGION, put); + LOG.info("Updated region " + regionInfo + " to ROOT"); + return true; + } + }; + MetaReader.fullScan( + masterServices.getCatalogTracker().waitForRootServerConnectionDefault(), + v, HRegionInfo.ROOT_REGIONINFO.getRegionName()); + return htds; + } + public static HRegionInfo090x getHRegionInfoForMigration( Result data) throws IOException { HRegionInfo090x info = null;