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 ;
@@ -640,57 +640,16 @@ public void copyAsync(DataObject srcData, DataObject dstData, AsyncCompletionCal
640640 SnapshotDataStoreVO snap = getSnapshotImageStoreRef (sinfo .getId (), vinfo .getDataCenterId ());
641641 SnapshotDetailsVO snapshotDetail = snapshotDetailsDao .findDetail (sinfo .getId (), StorPoolUtil .SP_DELAY_DELETE );
642642 if (snapshotDetail != null ) {
643- err = String .format ("Could not create volume from snapshot due to: %s" , resp .getError ());
643+ err = String .format ("Could not create volume from snapshot due to: %s. The snapshot was created with the delayDelete option. " , resp .getError ());
644644 } 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- }
645+ SpApiResponse emptyVolumeCreateResp = StorPoolUtil .volumeCreate (volumeName , null , size , null , null , "volume" , null , conn );
646+ if (emptyVolumeCreateResp .getError () == null ) {
647+ answer = createVolumeFromSnapshot (srcData , dstData , size , emptyVolumeCreateResp );
689648 } else {
690- err = String .format ("Could not create Storpool volume %s from snapshot %s. Error: %s" , volumeName , snapshotName , resp .getError ());
649+ answer = new Answer ( cmd , false , String .format ("Could not create Storpool volume %s from snapshot %s. Error: %s" , volumeName , snapshotName , emptyVolumeCreateResp .getError () ));
691650 }
692651 } else {
693- err = String .format ("The snapshot %s does not exists neither on primary, neither on secondary storage. Cannot create volume from snapshot" , snapshotName );
652+ 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 ) );
694653 }
695654 } else {
696655 err = String .format ("Could not create Storpool volume %s from snapshot %s. Error: %s" , volumeName , snapshotName , resp .getError ());
@@ -791,22 +750,17 @@ public void copyAsync(DataObject srcData, DataObject dstData, AsyncCompletionCal
791750 err = String .format ("Could not create Storpool volume for CS template %s. Error: %s" , name , resp .getError ());
792751 } else {
793752 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- }
753+ TemplateObjectTO dstTO = (TemplateObjectTO ) dstData .getTO ();
754+
755+ answer = createVolumeSnapshot (cmd , size , conn , volumeNameToSnapshot , dstTO );
756+ StorPoolUtil .volumeDelete (volumeNameToSnapshot , conn );
804757 }
805758 } else {
806759 resp = StorPoolUtil .volumeCreate (name , null , size , null , "no" , "template" , null , conn );
807760 if (resp .getError () != null ) {
808761 err = String .format ("Could not create Storpool volume for CS template %s. Error: %s" , name , resp .getError ());
809762 } else {
763+ String volName = StorPoolUtil .getNameFromResponse (resp , true );
810764 TemplateObjectTO dstTO = (TemplateObjectTO )dstData .getTO ();
811765 dstTO .setPath (StorPoolUtil .devPath (StorPoolUtil .getNameFromResponse (resp , false )));
812766 dstTO .setSize (size );
@@ -822,19 +776,12 @@ public void copyAsync(DataObject srcData, DataObject dstData, AsyncCompletionCal
822776
823777 if (answer != null && answer .getResult ()) {
824778 // 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- }
779+ answer = createVolumeSnapshot (cmd , size , conn , volName , dstTO );
829780 } else {
830781 err = answer != null ? answer .getDetails () : "Unknown error while downloading template. Null answer returned." ;
831782 }
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 ()));
783+
784+ StorPoolUtil .volumeDelete (volName , conn );
838785 }
839786 }
840787 } else if (srcType == DataObjectType .TEMPLATE && dstType == DataObjectType .VOLUME ) {
@@ -1027,6 +974,42 @@ public void copyAsync(DataObject srcData, DataObject dstData, AsyncCompletionCal
1027974 callback .complete (res );
1028975 }
1029976
977+ private Answer createVolumeSnapshot (StorageSubSystemCommand cmd , Long size , SpConnectionDesc conn ,
978+ String volName , TemplateObjectTO dstTO ) {
979+ Answer answer ;
980+ SpApiResponse resp = StorPoolUtil .volumeSnapshot (volName , dstTO .getUuid (), null , "template" , null , conn );
981+ if (resp .getError () != null ) {
982+ answer = new Answer (cmd , false , String .format ("Could not snapshot volume. Error: %s" , resp .getError ()));
983+ } else {
984+ dstTO .setPath (StorPoolUtil .devPath (
985+ StorPoolUtil .getSnapshotNameFromResponse (resp , false , StorPoolUtil .GLOBAL_ID )));
986+ dstTO .setSize (size );
987+ answer = new CopyCmdAnswer (dstTO );
988+ }
989+ return answer ;
990+ }
991+
992+ private Answer createVolumeFromSnapshot (DataObject srcData , DataObject dstData , final Long size ,
993+ SpApiResponse emptyVolumeCreateResp ) {
994+ Answer answer ;
995+ String name = StorPoolUtil .getNameFromResponse (emptyVolumeCreateResp , false );
996+ VolumeObjectTO dstTO = (VolumeObjectTO ) dstData .getTO ();
997+ dstTO .setSize (size );
998+ dstTO .setPath (StorPoolUtil .devPath (name ));
999+ StorageSubSystemCommand cmd = new StorPoolDownloadTemplateCommand (srcData .getTO (), dstTO , StorPoolHelper .getTimeout (StorPoolHelper .PrimaryStorageDownloadWait , configDao ), VirtualMachineManager .ExecuteInSequence .value (), "volume" );
1000+
1001+ EndPoint ep = selector .select (srcData , dstData );
1002+ if (ep == null ) {
1003+ answer = new Answer (cmd , false , "\" No remote endpoint to send command, check if host or ssvm is down?\" " );
1004+ } else {
1005+ answer = ep .sendMessage (cmd );
1006+ }
1007+ if (answer == null || !answer .getResult ()) {
1008+ answer = new Answer (cmd , false , answer != null ? answer .getDetails () : "Unknown error while downloading template. Null answer returned." );
1009+ }
1010+ return answer ;
1011+ }
1012+
10301013 private void updateVolumePoolType (VolumeInfo vinfo ) {
10311014 VolumeVO volumeVO = volumeDao .findById (vinfo .getId ());
10321015 volumeVO .setPoolType (StoragePoolType .StorPool );
0 commit comments