2424
2525import javax .inject .Inject ;
2626
27+ import com .cloud .storage .dao .SnapshotDetailsVO ;
2728import org .apache .cloudstack .engine .subsystem .api .storage .ChapInfo ;
2829import org .apache .cloudstack .engine .subsystem .api .storage .CopyCommandResult ;
2930import org .apache .cloudstack .engine .subsystem .api .storage .CreateCmdResult ;
110111import com .cloud .storage .VolumeVO ;
111112import com .cloud .storage .dao .SnapshotDao ;
112113import com .cloud .storage .dao .SnapshotDetailsDao ;
113- import com .cloud .storage .dao .SnapshotDetailsVO ;
114114import com .cloud .storage .dao .StoragePoolHostDao ;
115115import com .cloud .storage .dao .VMTemplateDetailsDao ;
116116import com .cloud .storage .dao .VolumeDao ;
@@ -638,59 +638,15 @@ public void copyAsync(DataObject srcData, DataObject dstData, AsyncCompletionCal
638638 //check if snapshot is on secondary storage
639639 StorPoolUtil .spLog ("Snapshot %s does not exists on StorPool, will try to create a volume from a snapshot on secondary storage" , snapshotName );
640640 SnapshotDataStoreVO snap = getSnapshotImageStoreRef (sinfo .getId (), vinfo .getDataCenterId ());
641- SnapshotDetailsVO snapshotDetail = snapshotDetailsDao .findDetail (sinfo .getId (), StorPoolUtil .SP_DELAY_DELETE );
642- if (snapshotDetail != null ) {
643- err = String .format ("Could not create volume from snapshot due to: %s" , resp .getError ());
644- } else if (snap != null && StorPoolStorageAdaptor .getVolumeNameFromPath (snap .getInstallPath (), false ) == null ) {
645- resp = StorPoolUtil .volumeCreate (srcData .getUuid (), null , size , null , "no" , "snapshot" , sinfo .getBaseVolume ().getMaxIops (), conn );
646- if (resp .getError () == null ) {
647- VolumeObjectTO dstTO = (VolumeObjectTO ) dstData .getTO ();
648- dstTO .setSize (size );
649- dstTO .setPath (StorPoolUtil .devPath (StorPoolUtil .getNameFromResponse (resp , false )));
650- cmd = new StorPoolDownloadTemplateCommand (srcData .getTO (), dstTO , StorPoolHelper .getTimeout (StorPoolHelper .PrimaryStorageDownloadWait , configDao ), VirtualMachineManager .ExecuteInSequence .value (), "volume" );
651-
652- EndPoint ep = selector .select (srcData , dstData );
653- if (ep == null ) {
654- err = "No remote endpoint to send command, check if host or ssvm is down?" ;
655- } else {
656- answer = ep .sendMessage (cmd );
657- }
658-
659- if (answer != null && answer .getResult ()) {
660- SpApiResponse resp2 = StorPoolUtil .volumeFreeze (StorPoolUtil .getNameFromResponse (resp , true ), conn );
661- if (resp2 .getError () != null ) {
662- err = String .format ("Could not freeze Storpool volume %s. Error: %s" , srcData .getUuid (), resp2 .getError ());
663- } else {
664- String name = StorPoolUtil .getNameFromResponse (resp , false );
665- SnapshotDetailsVO snapshotDetails = snapshotDetailsDao .findDetail (sinfo .getId (), sinfo .getUuid ());
666- if (snapshotDetails != null ) {
667- StorPoolHelper .updateSnapshotDetailsValue (snapshotDetails .getId (), StorPoolUtil .devPath (name ), "snapshot" );
668- }else {
669- StorPoolHelper .addSnapshotDetails (sinfo .getId (), sinfo .getUuid (), StorPoolUtil .devPath (name ), snapshotDetailsDao );
670- }
671- resp = StorPoolUtil .volumeCreate (volumeName , StorPoolUtil .getNameFromResponse (resp , true ), size , null , null , "volume" , sinfo .getBaseVolume ().getMaxIops (), conn );
672- if (resp .getError () == null ) {
673- updateStoragePool (dstData .getDataStore ().getId (), size );
674-
675- VolumeObjectTO to = (VolumeObjectTO ) dstData .getTO ();
676- to .setPath (StorPoolUtil .devPath (StorPoolUtil .getNameFromResponse (resp , false )));
677- to .setSize (size );
678- // successfully downloaded snapshot to primary storage
679- answer = new CopyCmdAnswer (to );
680- StorPoolUtil .spLog ("Created volume=%s with uuid=%s from snapshot=%s with uuid=%s" , name , to .getUuid (), snapshotName , sinfo .getUuid ());
681-
682- } else {
683- err = String .format ("Could not create Storpool volume %s from snapshot %s. Error: %s" , volumeName , snapshotName , resp .getError ());
684- }
685- }
686- } else {
687- err = answer != null ? answer .getDetails () : "Unknown error while downloading template. Null answer returned." ;
688- }
641+ if (snap != null && StorPoolStorageAdaptor .getVolumeNameFromPath (snap .getInstallPath (), false ) == null ) {
642+ SpApiResponse emptyVolumeCreateResp = StorPoolUtil .volumeCreate (volumeName , null , size , null , null , "volume" , null , conn );
643+ if (emptyVolumeCreateResp .getError () == null ) {
644+ answer = createVolumeFromSnapshot (srcData , dstData , size , emptyVolumeCreateResp );
689645 } else {
690- err = String .format ("Could not create Storpool volume %s from snapshot %s. Error: %s" , volumeName , snapshotName , resp .getError ());
646+ answer = new Answer ( cmd , false , String .format ("Could not create Storpool volume %s from snapshot %s. Error: %s" , volumeName , snapshotName , emptyVolumeCreateResp .getError () ));
691647 }
692648 } else {
693- err = String .format ("The snapshot %s does not exists neither on primary, neither on secondary storage. Cannot create volume from snapshot" , snapshotName );
649+ answer = new Answer ( cmd , false , String .format ("The snapshot %s does not exists neither on primary, neither on secondary storage. Cannot create volume from snapshot" , snapshotName ) );
694650 }
695651 } else {
696652 err = String .format ("Could not create Storpool volume %s from snapshot %s. Error: %s" , volumeName , snapshotName , resp .getError ());
@@ -791,22 +747,17 @@ public void copyAsync(DataObject srcData, DataObject dstData, AsyncCompletionCal
791747 err = String .format ("Could not create Storpool volume for CS template %s. Error: %s" , name , resp .getError ());
792748 } else {
793749 String volumeNameToSnapshot = StorPoolUtil .getNameFromResponse (resp , true );
794- SpApiResponse resp2 = StorPoolUtil .volumeFreeze (volumeNameToSnapshot , conn );
795- if (resp2 .getError () != null ) {
796- err = String .format ("Could not freeze Storpool volume %s. Error: %s" , name , resp2 .getError ());
797- } else {
798- StorPoolUtil .spLog ("Storpool snapshot [%s] for a template exists. Creating template on Storpool with name [%s]" , tinfo .getUuid (), name );
799- TemplateObjectTO dstTO = (TemplateObjectTO ) dstData .getTO ();
800- dstTO .setPath (StorPoolUtil .devPath (StorPoolUtil .getNameFromResponse (resp , false )));
801- dstTO .setSize (size );
802- answer = new CopyCmdAnswer (dstTO );
803- }
750+ TemplateObjectTO dstTO = (TemplateObjectTO ) dstData .getTO ();
751+
752+ answer = createVolumeSnapshot (cmd , size , conn , volumeNameToSnapshot , dstTO );
753+ StorPoolUtil .volumeDelete (volumeNameToSnapshot , conn );
804754 }
805755 } else {
806756 resp = StorPoolUtil .volumeCreate (name , null , size , null , "no" , "template" , null , conn );
807757 if (resp .getError () != null ) {
808758 err = String .format ("Could not create Storpool volume for CS template %s. Error: %s" , name , resp .getError ());
809759 } else {
760+ String volName = StorPoolUtil .getNameFromResponse (resp , true );
810761 TemplateObjectTO dstTO = (TemplateObjectTO )dstData .getTO ();
811762 dstTO .setPath (StorPoolUtil .devPath (StorPoolUtil .getNameFromResponse (resp , false )));
812763 dstTO .setSize (size );
@@ -822,19 +773,12 @@ public void copyAsync(DataObject srcData, DataObject dstData, AsyncCompletionCal
822773
823774 if (answer != null && answer .getResult ()) {
824775 // successfully downloaded template to primary storage
825- SpApiResponse resp2 = StorPoolUtil .volumeFreeze (StorPoolUtil .getNameFromResponse (resp , true ), conn );
826- if (resp2 .getError () != null ) {
827- err = String .format ("Could not freeze Storpool volume %s. Error: %s" , name , resp2 .getError ());
828- }
776+ answer = createVolumeSnapshot (cmd , size , conn , volName , dstTO );
829777 } else {
830778 err = answer != null ? answer .getDetails () : "Unknown error while downloading template. Null answer returned." ;
831779 }
832- }
833- }
834- if (err != null ) {
835- resp = StorPoolUtil .volumeDelete (StorPoolUtil .getNameFromResponse (resp , true ), conn );
836- if (resp .getError () != null ) {
837- logger .warn (String .format ("Could not clean-up Storpool volume %s. Error: %s" , name , resp .getError ()));
780+
781+ StorPoolUtil .volumeDelete (volName , conn );
838782 }
839783 }
840784 } else if (srcType == DataObjectType .TEMPLATE && dstType == DataObjectType .VOLUME ) {
@@ -1027,6 +971,42 @@ public void copyAsync(DataObject srcData, DataObject dstData, AsyncCompletionCal
1027971 callback .complete (res );
1028972 }
1029973
974+ private Answer createVolumeSnapshot (StorageSubSystemCommand cmd , Long size , SpConnectionDesc conn ,
975+ String volName , TemplateObjectTO dstTO ) {
976+ Answer answer ;
977+ SpApiResponse resp2 = StorPoolUtil .volumeSnapshot (volName , dstTO .getUuid (), null , "template" , null , conn );
978+ if (resp2 .getError () != null ) {
979+ answer = new Answer (cmd , false , String .format ("Could not snapshot volume. Error: %s" , resp2 .getError ()));
980+ } else {
981+ dstTO .setPath (StorPoolUtil .devPath (
982+ StorPoolUtil .getSnapshotNameFromResponse (resp2 , false , StorPoolUtil .GLOBAL_ID )));
983+ dstTO .setSize (size );
984+ answer = new CopyCmdAnswer (dstTO );
985+ }
986+ return answer ;
987+ }
988+
989+ private Answer createVolumeFromSnapshot (DataObject srcData , DataObject dstData , final Long size ,
990+ SpApiResponse emptyVolumeCreateResp ) {
991+ Answer answer ;
992+ String name = StorPoolUtil .getNameFromResponse (emptyVolumeCreateResp , false );
993+ VolumeObjectTO dstTO = (VolumeObjectTO ) dstData .getTO ();
994+ dstTO .setSize (size );
995+ dstTO .setPath (StorPoolUtil .devPath (name ));
996+ StorageSubSystemCommand cmd1 = new StorPoolDownloadTemplateCommand (srcData .getTO (), dstTO , StorPoolHelper .getTimeout (StorPoolHelper .PrimaryStorageDownloadWait , configDao ), VirtualMachineManager .ExecuteInSequence .value (), "volume" );
997+
998+ EndPoint ep = selector .select (srcData , dstData );
999+ if (ep == null ) {
1000+ answer = new Answer (cmd1 , false , "\" No remote endpoint to send command, check if host or ssvm is down?\" " );
1001+ } else {
1002+ answer = ep .sendMessage (cmd1 );
1003+ }
1004+ if (answer == null || !answer .getResult ()) {
1005+ answer = new Answer (cmd1 , false , answer != null ? answer .getDetails () : "Unknown error while downloading template. Null answer returned." );
1006+ }
1007+ return answer ;
1008+ }
1009+
10301010 private void updateVolumePoolType (VolumeInfo vinfo ) {
10311011 VolumeVO volumeVO = volumeDao .findById (vinfo .getId ());
10321012 volumeVO .setPoolType (StoragePoolType .StorPool );
0 commit comments