protected void addRegion(Path tableDir, RegionInfo regionInfo, RegionVisitor visitor)
    throws IOException {
    boolean isMobRegion = MobUtils.isMobRegionInfo(regionInfo);
    try {
      Path baseDir = tableDir;
      // Open the RegionFS
      if (isMobRegion) {
        baseDir = CommonFSUtils.getTableDir(MobUtils.getMobHome(conf), regionInfo.getTable());
      }
      HRegionFileSystem regionFs =
        HRegionFileSystem.openRegionFromFileSystem(conf, rootFs, baseDir, regionInfo, true);
      monitor.rethrowException();

      // 1. dump region meta info into the snapshot directory
      LOG.debug("Storing region-info for snapshot.");
      Object regionData = visitor.regionOpen(regionInfo);
      monitor.rethrowException();

      // 2. iterate through all the stores in the region
      LOG.debug("Creating references for hfiles");

      // This ensures that we have an atomic view of the directory as long as we have < ls limit
      // (batch size of the files in a directory) on the namenode. Otherwise, we get back the files
      // in batches and may miss files being added/deleted. This could be more robust (iteratively
      // checking to see if we have all the files until we are sure), but the limit is currently
      // 1000 files/batch, far more than the number of store files under a single column family.
      for (ColumnFamilyDescriptor cfd : htd.getColumnFamilies()) {
        Object familyData = visitor.familyOpen(regionData, cfd.getName());
        monitor.rethrowException();
        StoreFileTracker tracker = null;
        if (isMobRegion) {
          // MOB regions are always using the default SFT implementation
          ColumnFamilyDescriptor defaultSFTCfd = ColumnFamilyDescriptorBuilder.newBuilder(cfd)
            .setValue(StoreFileTrackerFactory.TRACKER_IMPL,
              StoreFileTrackerFactory.Trackers.DEFAULT.name())
            .build();
          tracker = StoreFileTrackerFactory.create(conf, htd, defaultSFTCfd, regionFs);
        } else {
          tracker = StoreFileTrackerFactory.create(conf, htd, cfd, regionFs);
        }
        List<StoreFileInfo> storeFiles = tracker.load();
        if (storeFiles.isEmpty()) {
          LOG.debug("No files under family: {}", cfd.getNameAsString());
          continue;
        }
        // 2.1. build the snapshot reference for the store
        // iterate through all the store's files and create "references".
        addReferenceFiles(visitor, regionData, familyData, storeFiles, false);
        visitor.familyClose(regionData, familyData);
      }
      visitor.regionClose(regionData);
    } catch (IOException e) {
      // the mob directory might not be created yet, so do nothing when it is a mob region
      if (!isMobRegion) {
        throw e;
      }
    }
  }
Creates a 'manifest' for the specified region, by reading directly from the disk. This is used
by the "offline snapshot" when the table is disabled.
hbase-server/src/main/java/org/apache/hadoop/hbase/snapshot/SnapshotManifest.java