synchronized long cloneSnapshot(final SnapshotDescription snapshot,
    final TableDescriptor tableDescriptor, final NonceKey nonceKey, final boolean restoreAcl,
    final String customSFT) throws HBaseSnapshotException {
    TableName tableName = tableDescriptor.getTableName();

    // make sure we aren't running a snapshot on the same table
    if (isTableTakingAnySnapshot(tableName)) {
      throw new RestoreSnapshotException("Snapshot in progress on the restore table=" + tableName);
    }

    // make sure we aren't running a restore on the same table
    if (isRestoringTable(tableName)) {
      throw new RestoreSnapshotException("Restore already in progress on the table=" + tableName);
    }

    try {
      long procId = master.getMasterProcedureExecutor().submitProcedure(
        new CloneSnapshotProcedure(master.getMasterProcedureExecutor().getEnvironment(),
          tableDescriptor, snapshot, restoreAcl, customSFT),
        nonceKey);
      this.restoreTableToProcIdMap.put(tableName, procId);
      return procId;
    } catch (Exception e) {
      String msg = "Couldn't clone the snapshot="
        + ClientSnapshotDescriptionUtils.toString(snapshot) + " on table=" + tableName;
      LOG.error(msg, e);
      throw new RestoreSnapshotException(msg, e);
    }
  }
Clone the specified snapshot into a new table. The operation will fail if the destination table
has a snapshot or restore in progress.
@param snapshot        Snapshot Descriptor
@param tableDescriptor Table Descriptor of the table to create
@param nonceKey        unique identifier to prevent duplicated RPC
@return procId the ID of the clone snapshot procedure
hbase-server/src/main/java/org/apache/hadoop/hbase/master/snapshot/SnapshotManager.java