@Override
  @edu.umd.cs.findbugs.annotations.SuppressWarnings(value = "REC_CATCH_EXCEPTION",
      justification = "Intentional")
  public void process() {
    String msg = "Running " + snapshot.getType() + " table snapshot " + snapshot.getName() + " "
      + eventType + " on table " + snapshotTable;
    LOG.info(msg);
    MasterLock tableLockToRelease = this.tableLock;
    status.setStatus(msg);
    try {
      if (downgradeToSharedTableLock()) {
        // release the exclusive lock and hold the shared lock instead
        tableLockToRelease = master.getLockManager().createMasterLock(snapshotTable,
          LockType.SHARED, this.getClass().getName() + ": take snapshot " + snapshot.getName());
        tableLock.release();
        boolean isTableLockAcquired = tableLockToRelease.tryAcquire(this.lockAcquireTimeoutMs);
        if (!isTableLockAcquired) {
          LOG.error("Could not acquire shared lock on table {} in {} ms", snapshotTable,
            lockAcquireTimeoutMs);
          throw new IOException("Could not acquire shared lock on table " + snapshotTable);
        }
      }
      // If regions move after this meta scan, the region specific snapshot should fail, triggering
      // an external exception that gets captured here.

      // write down the snapshot info in the working directory
      SnapshotDescriptionUtils.writeSnapshotInfo(snapshot, workingDir, workingDirFs);
      snapshotManifest.addTableDescriptor(this.htd);
      monitor.rethrowException();

      List<Pair<RegionInfo, ServerName>> regionsAndLocations =
        master.getAssignmentManager().getTableRegionsAndLocations(snapshotTable, false);

      // run the snapshot
      snapshotRegions(regionsAndLocations);
      monitor.rethrowException();

      // flush the in-memory state, and write the single manifest
      status.setStatus("Consolidate snapshot: " + snapshot.getName());
      snapshotManifest.consolidate();

      // verify the snapshot is valid
      status.setStatus("Verifying snapshot: " + snapshot.getName());
      verifier.verifySnapshot(workingDir, true);

      // complete the snapshot, atomically moving from tmp to .snapshot dir.
      SnapshotDescriptionUtils.completeSnapshot(this.snapshotDir, this.workingDir, this.rootFs,
        this.workingDirFs, this.conf);
      finished = true;
      msg = "Snapshot " + snapshot.getName() + " of table " + snapshotTable + " completed";
      status.markComplete(msg);
      LOG.info(msg);
      metricsSnapshot.addSnapshot(status.getCompletionTimestamp() - status.getStartTime());
      if (master.getMasterCoprocessorHost() != null) {
        master.getMasterCoprocessorHost()
          .postCompletedSnapshotAction(ProtobufUtil.createSnapshotDesc(snapshot), this.htd);
      }
    } catch (Exception e) { // FindBugs: REC_CATCH_EXCEPTION
      status.abort("Failed to complete snapshot " + snapshot.getName() + " on table "
        + snapshotTable + " because " + e.getMessage());
      String reason = "Failed taking snapshot " + ClientSnapshotDescriptionUtils.toString(snapshot)
        + " due to exception:" + e.getMessage();
      LOG.error(reason, e);
      ForeignException ee = new ForeignException(reason, e);
      monitor.receive(ee);
      // need to mark this completed to close off and allow cleanup to happen.
      cancel(reason);
    } finally {
      LOG.debug("Launching cleanup of working dir:" + workingDir);
      try {
        // if the working dir is still present, the snapshot has failed. it is present we delete
        // it.
        if (workingDirFs.exists(workingDir) && !workingDirFs.delete(workingDir, true)) {
          LOG.error("Couldn't delete snapshot working directory: {}", workingDir);
        }
      } catch (IOException e) {
        LOG.error("Couldn't get or delete snapshot working directory: {}", workingDir, e);
      }
      if (LOG.isDebugEnabled()) {
        LOG.debug("Table snapshot journal : \n" + status.prettyPrintJournal());
      }
      tableLockToRelease.release();
    }
  }
Execute the core common portions of taking a snapshot. The {@link #snapshotRegions(List)} call
should get implemented for each snapshot flavor.
hbase-server/src/main/java/org/apache/hadoop/hbase/master/snapshot/TakeSnapshotHandler.java