public void createPhysicalCopy(String baseVolumeName,String cloneName,String cloneCPG) throws Exception {
  _log.info("3PARDriver: createPhysicalCopy enter");
  String baseVolumeSnapCPG=cloneCPG;
  String baseVolumeUserCPG=cloneCPG;
  ClientResponse clientResp=null;
  String payload=null;
  String secondPayload=null;
  payload="{\"action\":\"createPhysicalCopy\", \"parameters\": { \"destVolume\": \"" + cloneName + "\" , \"saveSnapshot\": "+ true+ "} }";
  final String path=MessageFormat.format(URI_CREATE_VOLUME_CLONE,baseVolumeName);
  _log.info(" 3PARDriver: createPhysicalCopy uri = {} payload {} secondPayload {}",path,payload,secondPayload);
  try {
    clientResp=post(path,payload);
    if (clientResp == null || clientResp.getStatus() != 201) {
      if (clientResp != null) {
        String errResp=getResponseDetails(clientResp);
        _log.info(" 3PARDriver: createPhysicalCopy destination clone volume absent, hence creating new volume for clone. Error Info : {}",errResp);
      }
      VolumeDetailsCommandResult volResult=null;
      try {
        volResult=getVolumeDetails(baseVolumeName);
      }
 catch (      Exception e) {
        _log.info("3PARDriver: createVolumeClone the specified volume {} for clone creation not found, its parent {}; continue with clone creation: {}.\n",baseVolumeName,cloneName,e.getMessage());
      }
      if (volResult != null) {
        baseVolumeUserCPG=volResult.getUserCPG();
        baseVolumeSnapCPG=volResult.getSnapCPG();
        Boolean tpvv=true;
        Boolean tdvv=false;
        if (volResult.getProvisioningType() == 6) {
          tdvv=true;
          tpvv=false;
        }
        _log.info("3PARDriver: createVolumeClone base volume exists, id {}, baseVolumeSnapCPG {} , baseVolumeUserCPG {} , copyOf {}, copyType {} , name {}, volume type {} - ",baseVolumeName,baseVolumeSnapCPG,baseVolumeUserCPG,volResult.getCopyOf(),volResult.getCopyType(),volResult.getName(),volResult.getProvisioningType());
        createVolume(cloneName,baseVolumeSnapCPG,tpvv,tdvv,volResult.getSizeMiB());
        try {
          volResult=getVolumeDetails(baseVolumeName);
        }
 catch (        Exception e) {
          _log.info("3PARDriver: createVolumeClone the specified clone volume {} not created successfully yet. error {}",cloneName,e.getMessage());
        }
        if (volResult != null) {
          clientResp=post(path,payload);
        }
 else {
          _log.info("3PARDriver: createVolumeClone unable to find the newly created volume, volResult is null");
        }
      }
 else {
        _log.info("3PARDriver: createVolumeClone base volume not found, volResult is null");
      }
    }
    if (clientResp == null) {
      _log.error("3PARDriver:There is no response from 3PAR");
      throw new HP3PARException("There is no response from 3PAR");
    }
 else     if (clientResp.getStatus() != 201) {
      String errResp=getResponseDetails(clientResp);
      _log.info("3PARDriver: createPhysicalCopy error resopnse : {} ",errResp);
      throw new HP3PARException(errResp);
    }
 else {
      _log.info("3PARDriver: createPhysicalCopy success");
    }
  }
 catch (  Exception e) {
    throw e;
  }
 finally {
    if (clientResp != null) {
      clientResp.close();
    }
    _log.info("3PARDriver: createPhysicalCopy leave");
  }
}

public void createPhysicalCopy ( String baseVolumeName , String cloneName , String cloneCPG ) throws Exception { _log . info ( "3PARDriver: createPhysicalCopy enter" ) ; String baseVolumeSnapCPG = cloneCPG ; String baseVolumeUserCPG = cloneCPG ; ClientResponse clientResp = null ; String payload = null ; String secondPayload = null ; payload = "{\"action\":\"createPhysicalCopy\", \"parameters\": { \"destVolume\": \"" + cloneName + "\" , \"saveSnapshot\": " + true + "} }" ; final String path = MessageFormat . format ( URI_CREATE_VOLUME_CLONE , baseVolumeName ) ; _log . info ( " 3PARDriver: createPhysicalCopy uri = {} payload {} secondPayload {}" , path , payload , secondPayload ) ; try { clientResp = post ( path , payload ) ; if ( clientResp == null || clientResp . getStatus ( ) != 201 ) { if ( clientResp != null ) { String errResp = getResponseDetails ( clientResp ) ; _log . info ( " 3PARDriver: createPhysicalCopy destination clone volume absent, hence creating new volume for clone. Error Info : {}" , errResp ) ; } VolumeDetailsCommandResult volResult = null ; try { volResult = getVolumeDetails ( baseVolumeName ) ; } catch ( Exception e ) { _log . info ( "3PARDriver: createVolumeClone the specified volume {} for clone creation not found, its parent {}; continue with clone creation: {}.\n" , baseVolumeName , cloneName , e . getMessage ( ) ) ; } if ( volResult != null ) { baseVolumeUserCPG = volResult . getUserCPG ( ) ; baseVolumeSnapCPG = volResult . getSnapCPG ( ) ; Boolean tpvv = true ; Boolean tdvv = false ; if ( volResult . getProvisioningType ( ) == 6 ) { tdvv = true ; tpvv = false ; } _log . info ( "3PARDriver: createVolumeClone base volume exists, id {}, baseVolumeSnapCPG {} , baseVolumeUserCPG {} , copyOf {}, copyType {} , name {}, volume type {} - " , baseVolumeName , baseVolumeSnapCPG , baseVolumeUserCPG , volResult . getCopyOf ( ) , volResult . getCopyType ( ) , volResult . getName ( ) , volResult . getProvisioningType ( ) ) ; createVolume ( cloneName , baseVolumeSnapCPG , tpvv , tdvv , volResult . getSizeMiB ( ) ) ; try { volResult = getVolumeDetails ( baseVolumeName ) ; } catch ( Exception e ) { _log . info ( "3PARDriver: createVolumeClone the specified clone volume {} not created successfully yet. error {}" , cloneName , e . getMessage ( ) ) ; } if ( volResult != null ) { clientResp = post ( path , payload ) ; } else { _log . info ( "3PARDriver: createVolumeClone unable to find the newly created volume, volResult is null" ) ; } } else { _log . info ( "3PARDriver: createVolumeClone base volume not found, volResult is null" ) ; } } if ( clientResp == null ) { _log . error ( "3PARDriver:There is no response from 3PAR" ) ; throw new HP3PARException ( "There is no response from 3PAR" ) ; } else if ( clientResp . getStatus ( ) != 201 ) { String errResp = getResponseDetails ( clientResp ) ; _log . info ( "3PARDriver: createPhysicalCopy error resopnse : {} " , errResp ) ; throw new HP3PARException ( errResp ) ; } else { _log . info ( "3PARDriver: createPhysicalCopy success" ) ; } } catch ( Exception e ) { throw e ; } finally { if ( clientResp != null ) { clientResp . close ( ) ; } _log . info ( "3PARDriver: createPhysicalCopy leave" ) ; } }
vipr ui doesn ' t provide offline ( attached volume ) / online options while creating clone , so below logic will be followed : first , to check destination volume exists we execute create clone creation as offline volume . if error , destination clone volume doesn ' t exist , so create a new volume with clone name by using its base volume parameters like tpvv , cpg . then create a offline volume clone using newly created volume clone note : a offline clone creates a attached clone , which actually creates a intermediate snapshot which can be utilized for restore / update . we are not using online option , as it creates detached volume with no way to restore / update .
