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 ;
101102import com .cloud .storage .VolumeVO ;
102103import com .cloud .storage .dao .SnapshotDao ;
103104import com .cloud .storage .dao .SnapshotDetailsDao ;
104- import com .cloud .storage .dao .SnapshotDetailsVO ;
105105import com .cloud .storage .dao .StoragePoolHostDao ;
106106import com .cloud .storage .dao .VMTemplateDetailsDao ;
107107import com .cloud .storage .dao .VolumeDao ;
@@ -550,59 +550,15 @@ public void copyAsync(DataObject srcData, DataObject dstData, AsyncCompletionCal
550550 //check if snapshot is on secondary storage
551551 StorPoolUtil .spLog ("Snapshot %s does not exists on StorPool, will try to create a volume from a snapshot on secondary storage" , snapshotName );
552552 SnapshotDataStoreVO snap = getSnapshotImageStoreRef (sinfo .getId (), vinfo .getDataCenterId ());
553- SnapshotDetailsVO snapshotDetail = snapshotDetailsDao .findDetail (sinfo .getId (), StorPoolUtil .SP_DELAY_DELETE );
554- if (snapshotDetail != null ) {
555- err = String .format ("Could not create volume from snapshot due to: %s" , resp .getError ());
556- } else if (snap != null && StorPoolStorageAdaptor .getVolumeNameFromPath (snap .getInstallPath (), false ) == null ) {
557- resp = StorPoolUtil .volumeCreate (srcData .getUuid (), null , size , null , "no" , "snapshot" , sinfo .getBaseVolume ().getMaxIops (), conn );
558- if (resp .getError () == null ) {
559- VolumeObjectTO dstTO = (VolumeObjectTO ) dstData .getTO ();
560- dstTO .setSize (size );
561- dstTO .setPath (StorPoolUtil .devPath (StorPoolUtil .getNameFromResponse (resp , false )));
562- cmd = new StorPoolDownloadTemplateCommand (srcData .getTO (), dstTO , StorPoolHelper .getTimeout (StorPoolHelper .PrimaryStorageDownloadWait , configDao ), VirtualMachineManager .ExecuteInSequence .value (), "volume" );
563-
564- EndPoint ep = selector .select (srcData , dstData );
565- if (ep == null ) {
566- err = "No remote endpoint to send command, check if host or ssvm is down?" ;
567- } else {
568- answer = ep .sendMessage (cmd );
569- }
570-
571- if (answer != null && answer .getResult ()) {
572- SpApiResponse resp2 = StorPoolUtil .volumeFreeze (StorPoolUtil .getNameFromResponse (resp , true ), conn );
573- if (resp2 .getError () != null ) {
574- err = String .format ("Could not freeze Storpool volume %s. Error: %s" , srcData .getUuid (), resp2 .getError ());
575- } else {
576- String name = StorPoolUtil .getNameFromResponse (resp , false );
577- SnapshotDetailsVO snapshotDetails = snapshotDetailsDao .findDetail (sinfo .getId (), sinfo .getUuid ());
578- if (snapshotDetails != null ) {
579- StorPoolHelper .updateSnapshotDetailsValue (snapshotDetails .getId (), StorPoolUtil .devPath (name ), "snapshot" );
580- }else {
581- StorPoolHelper .addSnapshotDetails (sinfo .getId (), sinfo .getUuid (), StorPoolUtil .devPath (name ), snapshotDetailsDao );
582- }
583- resp = StorPoolUtil .volumeCreate (volumeName , StorPoolUtil .getNameFromResponse (resp , true ), size , null , null , "volume" , sinfo .getBaseVolume ().getMaxIops (), conn );
584- if (resp .getError () == null ) {
585- updateStoragePool (dstData .getDataStore ().getId (), size );
586-
587- VolumeObjectTO to = (VolumeObjectTO ) dstData .getTO ();
588- to .setPath (StorPoolUtil .devPath (StorPoolUtil .getNameFromResponse (resp , false )));
589- to .setSize (size );
590- // successfully downloaded snapshot to primary storage
591- answer = new CopyCmdAnswer (to );
592- StorPoolUtil .spLog ("Created volume=%s with uuid=%s from snapshot=%s with uuid=%s" , name , to .getUuid (), snapshotName , sinfo .getUuid ());
593-
594- } else {
595- err = String .format ("Could not create Storpool volume %s from snapshot %s. Error: %s" , volumeName , snapshotName , resp .getError ());
596- }
597- }
598- } else {
599- err = answer != null ? answer .getDetails () : "Unknown error while downloading template. Null answer returned." ;
600- }
553+ if (snap != null && StorPoolStorageAdaptor .getVolumeNameFromPath (snap .getInstallPath (), false ) == null ) {
554+ SpApiResponse emptyVolumeCreateResp = StorPoolUtil .volumeCreate (volumeName , null , size , null , null , "volume" , null , conn );
555+ if (emptyVolumeCreateResp .getError () == null ) {
556+ answer = createVolumeFromSnapshot (srcData , dstData , size , emptyVolumeCreateResp );
601557 } else {
602- err = String .format ("Could not create Storpool volume %s from snapshot %s. Error: %s" , volumeName , snapshotName , resp .getError ());
558+ answer = new Answer ( cmd , false , String .format ("Could not create Storpool volume %s from snapshot %s. Error: %s" , volumeName , snapshotName , emptyVolumeCreateResp .getError () ));
603559 }
604560 } else {
605- err = String .format ("The snapshot %s does not exists neither on primary, neither on secondary storage. Cannot create volume from snapshot" , snapshotName );
561+ 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 ) );
606562 }
607563 } else {
608564 err = String .format ("Could not create Storpool volume %s from snapshot %s. Error: %s" , volumeName , snapshotName , resp .getError ());
@@ -703,22 +659,17 @@ public void copyAsync(DataObject srcData, DataObject dstData, AsyncCompletionCal
703659 err = String .format ("Could not create Storpool volume for CS template %s. Error: %s" , name , resp .getError ());
704660 } else {
705661 String volumeNameToSnapshot = StorPoolUtil .getNameFromResponse (resp , true );
706- SpApiResponse resp2 = StorPoolUtil .volumeFreeze (volumeNameToSnapshot , conn );
707- if (resp2 .getError () != null ) {
708- err = String .format ("Could not freeze Storpool volume %s. Error: %s" , name , resp2 .getError ());
709- } else {
710- StorPoolUtil .spLog ("Storpool snapshot [%s] for a template exists. Creating template on Storpool with name [%s]" , tinfo .getUuid (), name );
711- TemplateObjectTO dstTO = (TemplateObjectTO ) dstData .getTO ();
712- dstTO .setPath (StorPoolUtil .devPath (StorPoolUtil .getNameFromResponse (resp , false )));
713- dstTO .setSize (size );
714- answer = new CopyCmdAnswer (dstTO );
715- }
662+ TemplateObjectTO dstTO = (TemplateObjectTO ) dstData .getTO ();
663+
664+ answer = createVolumeSnapshot (cmd , size , conn , volumeNameToSnapshot , dstTO );
665+ StorPoolUtil .volumeDelete (volumeNameToSnapshot , conn );
716666 }
717667 } else {
718668 resp = StorPoolUtil .volumeCreate (name , null , size , null , "no" , "template" , null , conn );
719669 if (resp .getError () != null ) {
720670 err = String .format ("Could not create Storpool volume for CS template %s. Error: %s" , name , resp .getError ());
721671 } else {
672+ String volName = StorPoolUtil .getNameFromResponse (resp , true );
722673 TemplateObjectTO dstTO = (TemplateObjectTO )dstData .getTO ();
723674 dstTO .setPath (StorPoolUtil .devPath (StorPoolUtil .getNameFromResponse (resp , false )));
724675 dstTO .setSize (size );
@@ -734,19 +685,12 @@ public void copyAsync(DataObject srcData, DataObject dstData, AsyncCompletionCal
734685
735686 if (answer != null && answer .getResult ()) {
736687 // successfully downloaded template to primary storage
737- SpApiResponse resp2 = StorPoolUtil .volumeFreeze (StorPoolUtil .getNameFromResponse (resp , true ), conn );
738- if (resp2 .getError () != null ) {
739- err = String .format ("Could not freeze Storpool volume %s. Error: %s" , name , resp2 .getError ());
740- }
688+ answer = createVolumeSnapshot (cmd , size , conn , volName , dstTO );
741689 } else {
742690 err = answer != null ? answer .getDetails () : "Unknown error while downloading template. Null answer returned." ;
743691 }
744- }
745- }
746- if (err != null ) {
747- resp = StorPoolUtil .volumeDelete (StorPoolUtil .getNameFromResponse (resp , true ), conn );
748- if (resp .getError () != null ) {
749- logger .warn (String .format ("Could not clean-up Storpool volume %s. Error: %s" , name , resp .getError ()));
692+
693+ StorPoolUtil .volumeDelete (volName , conn );
750694 }
751695 }
752696 } else if (srcType == DataObjectType .TEMPLATE && dstType == DataObjectType .VOLUME ) {
@@ -917,6 +861,42 @@ public void copyAsync(DataObject srcData, DataObject dstData, AsyncCompletionCal
917861 callback .complete (res );
918862 }
919863
864+ private Answer createVolumeSnapshot (StorageSubSystemCommand cmd , Long size , SpConnectionDesc conn ,
865+ String volName , TemplateObjectTO dstTO ) {
866+ Answer answer ;
867+ SpApiResponse resp2 = StorPoolUtil .volumeSnapshot (volName , dstTO .getUuid (), null , "template" , null , conn );
868+ if (resp2 .getError () != null ) {
869+ answer = new Answer (cmd , false , String .format ("Could not snapshot volume. Error: %s" , resp2 .getError ()));
870+ } else {
871+ dstTO .setPath (StorPoolUtil .devPath (
872+ StorPoolUtil .getSnapshotNameFromResponse (resp2 , false , StorPoolUtil .GLOBAL_ID )));
873+ dstTO .setSize (size );
874+ answer = new CopyCmdAnswer (dstTO );
875+ }
876+ return answer ;
877+ }
878+
879+ private Answer createVolumeFromSnapshot (DataObject srcData , DataObject dstData , final Long size ,
880+ SpApiResponse emptyVolumeCreateResp ) {
881+ Answer answer ;
882+ String name = StorPoolUtil .getNameFromResponse (emptyVolumeCreateResp , false );
883+ VolumeObjectTO dstTO = (VolumeObjectTO ) dstData .getTO ();
884+ dstTO .setSize (size );
885+ dstTO .setPath (StorPoolUtil .devPath (name ));
886+ StorageSubSystemCommand cmd1 = new StorPoolDownloadTemplateCommand (srcData .getTO (), dstTO , StorPoolHelper .getTimeout (StorPoolHelper .PrimaryStorageDownloadWait , configDao ), VirtualMachineManager .ExecuteInSequence .value (), "volume" );
887+
888+ EndPoint ep = selector .select (srcData , dstData );
889+ if (ep == null ) {
890+ answer = new Answer (cmd1 , false , "\" No remote endpoint to send command, check if host or ssvm is down?\" " );
891+ } else {
892+ answer = ep .sendMessage (cmd1 );
893+ }
894+ if (answer == null || !answer .getResult ()) {
895+ answer = new Answer (cmd1 , false , answer != null ? answer .getDetails () : "Unknown error while downloading template. Null answer returned." );
896+ }
897+ return answer ;
898+ }
899+
920900 private void updateVolumePoolType (VolumeInfo vinfo ) {
921901 VolumeVO volumeVO = volumeDao .findById (vinfo .getId ());
922902 volumeVO .setPoolType (StoragePoolType .StorPool );
0 commit comments