@Override
  protected Flow executeFromState(MasterProcedureEnv env, SnapshotState state)
    throws ProcedureSuspendedException, ProcedureYieldException, InterruptedException {
    LOG.info("{} execute state={}", this, state);

    try {
      switch (state) {
        case SNAPSHOT_PREPARE:
          prepareSnapshot(env);
          setNextState(SnapshotState.SNAPSHOT_PRE_OPERATION);
          return Flow.HAS_MORE_STATE;
        case SNAPSHOT_PRE_OPERATION:
          preSnapshot(env);
          setNextState(SnapshotState.SNAPSHOT_WRITE_SNAPSHOT_INFO);
          return Flow.HAS_MORE_STATE;
        case SNAPSHOT_WRITE_SNAPSHOT_INFO:
          SnapshotDescriptionUtils.writeSnapshotInfo(snapshot, workingDir, workingDirFS);
          TableState tableState =
            env.getMasterServices().getTableStateManager().getTableState(snapshotTable);
          if (tableState.isEnabled()) {
            setNextState(SnapshotState.SNAPSHOT_SNAPSHOT_ONLINE_REGIONS);
          } else if (tableState.isDisabled()) {
            setNextState(SnapshotState.SNAPSHOT_SNAPSHOT_CLOSED_REGIONS);
          }
          return Flow.HAS_MORE_STATE;
        case SNAPSHOT_SNAPSHOT_ONLINE_REGIONS:
          addChildProcedure(createRemoteSnapshotProcedures(env));
          setNextState(SnapshotState.SNAPSHOT_SNAPSHOT_SPLIT_REGIONS);
          return Flow.HAS_MORE_STATE;
        case SNAPSHOT_SNAPSHOT_SPLIT_REGIONS:
          snapshotSplitRegions(env);
          setNextState(SnapshotState.SNAPSHOT_SNAPSHOT_MOB_REGION);
          return Flow.HAS_MORE_STATE;
        case SNAPSHOT_SNAPSHOT_CLOSED_REGIONS:
          snapshotClosedRegions(env);
          setNextState(SnapshotState.SNAPSHOT_SNAPSHOT_MOB_REGION);
          return Flow.HAS_MORE_STATE;
        case SNAPSHOT_SNAPSHOT_MOB_REGION:
          snapshotMobRegion(env);
          setNextState(SnapshotState.SNAPSHOT_CONSOLIDATE_SNAPSHOT);
          return Flow.HAS_MORE_STATE;
        case SNAPSHOT_CONSOLIDATE_SNAPSHOT:
          // flush the in-memory state, and write the single manifest
          status.setStatus("Consolidate snapshot: " + snapshot.getName());
          snapshotManifest.consolidate();
          setNextState(SnapshotState.SNAPSHOT_VERIFIER_SNAPSHOT);
          return Flow.HAS_MORE_STATE;
        case SNAPSHOT_VERIFIER_SNAPSHOT:
          status.setStatus("Verifying snapshot: " + snapshot.getName());
          verifySnapshot(env);
          setNextState(SnapshotState.SNAPSHOT_COMPLETE_SNAPSHOT);
          return Flow.HAS_MORE_STATE;
        case SNAPSHOT_COMPLETE_SNAPSHOT:
          if (isSnapshotCorrupted()) {
            throw new CorruptedSnapshotException(snapshot.getName());
          }
          completeSnapshot(env);
          setNextState(SnapshotState.SNAPSHOT_POST_OPERATION);
          return Flow.HAS_MORE_STATE;
        case SNAPSHOT_POST_OPERATION:
          postSnapshot(env);
          return Flow.NO_MORE_STATE;
        default:
          throw new UnsupportedOperationException("unhandled state=" + state);
      }
    } catch (ProcedureSuspendedException e) {
      throw e;
    } catch (Exception e) {
      setFailure("master-snapshot", e);
      LOG.warn("unexpected exception while execute {}. Mark procedure Failed.", this, e);
      status.abort("Abort Snapshot " + snapshot.getName() + " on Table " + snapshotTable);
      return Flow.NO_MORE_STATE;
    }
  }
A procedure used to take snapshot on tables.
hbase-server/src/main/java/org/apache/hadoop/hbase/master/procedure/SnapshotProcedure.java