Updated Branches:
  refs/heads/object_store 564d3d6fa -> 68ffe1c70

fix bug in create volume from snapshot


Project: http://git-wip-us.apache.org/repos/asf/cloudstack/repo
Commit: http://git-wip-us.apache.org/repos/asf/cloudstack/commit/68ffe1c7
Tree: http://git-wip-us.apache.org/repos/asf/cloudstack/tree/68ffe1c7
Diff: http://git-wip-us.apache.org/repos/asf/cloudstack/diff/68ffe1c7

Branch: refs/heads/object_store
Commit: 68ffe1c70692b04a667e7954cc8b2fd6188403cf
Parents: 564d3d6
Author: Edison Su <[email protected]>
Authored: Tue May 14 16:20:20 2013 -0700
Committer: Edison Su <[email protected]>
Committed: Tue May 14 16:38:02 2013 -0700

----------------------------------------------------------------------
 .../cloud/storage/resource/StorageProcessor.java   |    1 +
 .../StorageSubsystemCommandHandlerBase.java        |    2 +
 .../storage/motion/AncientDataMotionStrategy.java  |   11 +-
 .../cloudstack/storage/test/SnapshotTest.java      |   24 +++-
 .../storage/volume/VolumeServiceImpl.java          |    6 +-
 .../kvm/storage/KVMStorageProcessor.java           |   58 ++++++--
 .../storage/resource/VmwareStorageProcessor.java   |  118 +++++++++++++++
 .../xen/resource/XenServerStorageProcessor.java    |   68 +++++++++
 8 files changed, 266 insertions(+), 22 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/cloudstack/blob/68ffe1c7/core/src/com/cloud/storage/resource/StorageProcessor.java
----------------------------------------------------------------------
diff --git a/core/src/com/cloud/storage/resource/StorageProcessor.java 
b/core/src/com/cloud/storage/resource/StorageProcessor.java
index ec965ed..86bfe4b 100644
--- a/core/src/com/cloud/storage/resource/StorageProcessor.java
+++ b/core/src/com/cloud/storage/resource/StorageProcessor.java
@@ -42,4 +42,5 @@ public interface StorageProcessor {
     public Answer createVolume(CreateObjectCommand cmd);
     public Answer createSnapshot(CreateObjectCommand cmd);
     public Answer deleteVolume(DeleteCommand cmd);
+    public Answer createVolumeFromSnapshot(CopyCommand cmd);
 }

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/68ffe1c7/core/src/com/cloud/storage/resource/StorageSubsystemCommandHandlerBase.java
----------------------------------------------------------------------
diff --git 
a/core/src/com/cloud/storage/resource/StorageSubsystemCommandHandlerBase.java 
b/core/src/com/cloud/storage/resource/StorageSubsystemCommandHandlerBase.java
index 8f76e93..d167d61 100644
--- 
a/core/src/com/cloud/storage/resource/StorageSubsystemCommandHandlerBase.java
+++ 
b/core/src/com/cloud/storage/resource/StorageSubsystemCommandHandlerBase.java
@@ -82,6 +82,8 @@ public class StorageSubsystemCommandHandlerBase implements 
StorageSubsystemComma
             }
         } else if (srcData.getObjectType() == DataObjectType.SNAPSHOT && 
srcData.getDataStore().getRole() == DataStoreRole.Primary) {
             return processor.backupSnasphot(cmd);
+        } else if (srcData.getObjectType() == DataObjectType.SNAPSHOT && 
destData.getObjectType() == DataObjectType.VOLUME) {
+               return processor.createVolumeFromSnapshot(cmd);
         }
 
         return new Answer(cmd, false, "not implemented yet");

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/68ffe1c7/engine/storage/datamotion/src/org/apache/cloudstack/storage/motion/AncientDataMotionStrategy.java
----------------------------------------------------------------------
diff --git 
a/engine/storage/datamotion/src/org/apache/cloudstack/storage/motion/AncientDataMotionStrategy.java
 
b/engine/storage/datamotion/src/org/apache/cloudstack/storage/motion/AncientDataMotionStrategy.java
index 4bd290b..73be162 100644
--- 
a/engine/storage/datamotion/src/org/apache/cloudstack/storage/motion/AncientDataMotionStrategy.java
+++ 
b/engine/storage/datamotion/src/org/apache/cloudstack/storage/motion/AncientDataMotionStrategy.java
@@ -231,12 +231,11 @@ public class AncientDataMotionStrategy implements 
DataMotionStrategy {
                             .getDefaultValue()));
 
             CopyCommand cmd = new CopyCommand(srcData.getTO(), volObj.getTO(), 
_createVolumeFromSnapshotWait);
-
-
-            Answer answer = storageMgr
-                    .sendToPool(pool, cmd);
+            EndPoint ep = selector.select(snapObj, volObj);
+            Answer answer = ep.sendMessage(cmd);
+           
            return answer;
-        } catch (StorageUnavailableException e) {
+        } catch (Exception e) {
             s_logger.error(basicErrMsg, e);
             throw new CloudRuntimeException(basicErrMsg);
         } finally {
@@ -300,7 +299,7 @@ public class AncientDataMotionStrategy implements 
DataMotionStrategy {
             } else if (srcData.getType() == DataObjectType.SNAPSHOT &&
                        destData.getType() == DataObjectType.SNAPSHOT) {
                answer = copySnapshot(srcData, destData);
-            }
+            } 
 
             if (answer != null && !answer.getResult()) {
                 errMsg = answer.getDetails();

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/68ffe1c7/engine/storage/integration-test/test/org/apache/cloudstack/storage/test/SnapshotTest.java
----------------------------------------------------------------------
diff --git 
a/engine/storage/integration-test/test/org/apache/cloudstack/storage/test/SnapshotTest.java
 
b/engine/storage/integration-test/test/org/apache/cloudstack/storage/test/SnapshotTest.java
index d667a78..264db68 100644
--- 
a/engine/storage/integration-test/test/org/apache/cloudstack/storage/test/SnapshotTest.java
+++ 
b/engine/storage/integration-test/test/org/apache/cloudstack/storage/test/SnapshotTest.java
@@ -360,7 +360,7 @@ public class SnapshotTest extends CloudStackTestNGBase {
         return null;
     }
 
-    @Test
+    //@Test
     public void createSnapshot() {
         VolumeInfo vol = createCopyBaseImage();
         SnapshotVO snapshotVO = createSnapshotInDb(vol);
@@ -394,7 +394,7 @@ public class SnapshotTest extends CloudStackTestNGBase {
         return image;
     }
 
-    @Test
+    //@Test
     public void createTemplateFromSnapshot() {
         VolumeInfo vol = createCopyBaseImage();
         SnapshotVO snapshotVO = createSnapshotInDb(vol);
@@ -416,4 +416,24 @@ public class SnapshotTest extends CloudStackTestNGBase {
         DataStore imageStore = this.dataStoreMgr.getImageStore(this.dcId);
         this.imageService.createTemplateFromSnapshotAsync(snapshot, tmpl, 
imageStore);
     }
+    
+    @Test
+    public void createVolumeFromSnapshot() {
+        VolumeInfo vol = createCopyBaseImage();
+        SnapshotVO snapshotVO = createSnapshotInDb(vol);
+        SnapshotInfo snapshot = 
this.snapshotFactory.getSnapshot(snapshotVO.getId(), vol.getDataStore());
+        boolean result = false;
+        for (SnapshotStrategy strategy : this.snapshotStrategies) {
+            if (strategy.canHandle(snapshot)) {
+                snapshot = strategy.takeSnapshot(snapshot);
+                result = true;
+            }
+        }
+
+        AssertJUnit.assertTrue(result);
+
+        VolumeVO volVO = createVolume(vol.getTemplateId(), vol.getPoolId());
+        VolumeInfo newVol = this.volFactory.getVolume(volVO.getId());
+        this.volumeService.createVolumeFromSnapshot(newVol, 
newVol.getDataStore(), snapshot);
+    }
 }

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/68ffe1c7/engine/storage/volume/src/org/apache/cloudstack/storage/volume/VolumeServiceImpl.java
----------------------------------------------------------------------
diff --git 
a/engine/storage/volume/src/org/apache/cloudstack/storage/volume/VolumeServiceImpl.java
 
b/engine/storage/volume/src/org/apache/cloudstack/storage/volume/VolumeServiceImpl.java
index 414f802..bd6df57 100644
--- 
a/engine/storage/volume/src/org/apache/cloudstack/storage/volume/VolumeServiceImpl.java
+++ 
b/engine/storage/volume/src/org/apache/cloudstack/storage/volume/VolumeServiceImpl.java
@@ -539,7 +539,11 @@ public class VolumeServiceImpl implements VolumeService {
        }
 
        try {
-               volume.processEvent(event);
+               if (result.isSuccess()) {
+                       volume.processEvent(event, result.getAnswer());
+               } else {
+                       volume.processEvent(event);
+               }
                snapshot.processEvent(event);
        } catch (Exception e) {
                s_logger.debug("create volume from snapshot failed", e);

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/68ffe1c7/plugins/hypervisors/kvm/src/com/cloud/hypervisor/kvm/storage/KVMStorageProcessor.java
----------------------------------------------------------------------
diff --git 
a/plugins/hypervisors/kvm/src/com/cloud/hypervisor/kvm/storage/KVMStorageProcessor.java
 
b/plugins/hypervisors/kvm/src/com/cloud/hypervisor/kvm/storage/KVMStorageProcessor.java
index 3bdf428..c3fa12b 100644
--- 
a/plugins/hypervisors/kvm/src/com/cloud/hypervisor/kvm/storage/KVMStorageProcessor.java
+++ 
b/plugins/hypervisors/kvm/src/com/cloud/hypervisor/kvm/storage/KVMStorageProcessor.java
@@ -20,7 +20,6 @@ package com.cloud.hypervisor.kvm.storage;
 
 import java.io.File;
 import java.io.FileOutputStream;
-import java.io.IOException;
 import java.net.URISyntaxException;
 import java.text.DateFormat;
 import java.text.MessageFormat;
@@ -47,9 +46,9 @@ import org.apache.cloudstack.storage.to.SnapshotObjectTO;
 import org.apache.cloudstack.storage.to.TemplateObjectTO;
 import org.apache.cloudstack.storage.to.VolumeObjectTO;
 import org.apache.cloudstack.utils.qemu.QemuImg;
+import org.apache.cloudstack.utils.qemu.QemuImg.PhysicalDiskFormat;
 import org.apache.cloudstack.utils.qemu.QemuImgException;
 import org.apache.cloudstack.utils.qemu.QemuImgFile;
-import org.apache.cloudstack.utils.qemu.QemuImg.PhysicalDiskFormat;
 import org.apache.log4j.Logger;
 import org.libvirt.Connect;
 import org.libvirt.Domain;
@@ -58,37 +57,28 @@ import org.libvirt.DomainSnapshot;
 import org.libvirt.LibvirtException;
 
 import com.cloud.agent.api.Answer;
-import com.cloud.agent.api.AttachVolumeAnswer;
-import com.cloud.agent.api.BackupSnapshotAnswer;
-import com.cloud.agent.api.ManageSnapshotAnswer;
-import com.cloud.agent.api.ManageSnapshotCommand;
-import com.cloud.agent.api.storage.CreateAnswer;
-import com.cloud.agent.api.storage.CreatePrivateTemplateAnswer;
 import com.cloud.agent.api.storage.PrimaryStorageDownloadAnswer;
 import com.cloud.agent.api.to.DataStoreTO;
 import com.cloud.agent.api.to.DataTO;
 import com.cloud.agent.api.to.DiskTO;
 import com.cloud.agent.api.to.NfsTO;
-import com.cloud.agent.api.to.StorageFilerTO;
-import com.cloud.agent.api.to.VolumeTO;
 import com.cloud.exception.InternalErrorException;
 import com.cloud.hypervisor.kvm.resource.LibvirtComputingResource;
 import com.cloud.hypervisor.kvm.resource.LibvirtConnection;
 import com.cloud.hypervisor.kvm.resource.LibvirtDomainXMLParser;
 import com.cloud.hypervisor.kvm.resource.LibvirtVMDef.DiskDef;
 import com.cloud.storage.JavaStorageLayer;
-import com.cloud.storage.StorageLayer;
 import com.cloud.storage.Storage.ImageFormat;
 import com.cloud.storage.Storage.StoragePoolType;
+import com.cloud.storage.StorageLayer;
 import com.cloud.storage.resource.StorageProcessor;
 import com.cloud.storage.template.Processor;
+import com.cloud.storage.template.Processor.FormatInfo;
 import com.cloud.storage.template.QCOW2Processor;
 import com.cloud.storage.template.TemplateLocation;
-import com.cloud.storage.template.Processor.FormatInfo;
 import com.cloud.utils.NumbersUtil;
 import com.cloud.utils.exception.CloudRuntimeException;
 import com.cloud.utils.script.Script;
-import com.cloud.vm.DiskProfile;
 
 public class KVMStorageProcessor implements StorageProcessor {
     private static final Logger s_logger = 
Logger.getLogger(KVMStorageProcessor.class);
@@ -870,4 +860,46 @@ public class KVMStorageProcessor implements 
StorageProcessor {
         }
     }
 
+    @Override
+    public Answer createVolumeFromSnapshot(CopyCommand cmd) {
+       try {
+               DataTO srcData = cmd.getSrcTO();
+               SnapshotObjectTO snapshot = (SnapshotObjectTO)srcData;
+               DataTO destData = cmd.getDestTO();
+               PrimaryDataStoreTO pool = 
(PrimaryDataStoreTO)destData.getDataStore();
+               DataStoreTO imageStore = srcData.getDataStore();
+
+
+               if (!(imageStore instanceof NfsTO)) {
+                       return new CopyCmdAnswer("unsupported protocol");
+               }
+
+               NfsTO nfsImageStore = (NfsTO)imageStore;
+
+               String snapshotPath = snapshot.getPath();
+               int index = snapshotPath.lastIndexOf("/");
+               snapshotPath = snapshotPath.substring(0, index);
+               String snapshotName = snapshotPath.substring(index + 1);
+               KVMStoragePool secondaryPool = 
storagePoolMgr.getStoragePoolByURI(
+                               nfsImageStore.getUrl() + File.separator + 
snapshotPath);
+               KVMPhysicalDisk snapshotDisk = 
secondaryPool.getPhysicalDisk(snapshotName);
+
+               String primaryUuid = pool.getUuid();
+               KVMStoragePool primaryPool = storagePoolMgr
+                               .getStoragePool(pool.getPoolType(),
+                                               primaryUuid);
+               String volUuid = UUID.randomUUID().toString();
+               KVMPhysicalDisk disk = 
storagePoolMgr.copyPhysicalDisk(snapshotDisk,
+                               volUuid, primaryPool);
+               VolumeObjectTO newVol = new VolumeObjectTO();
+               newVol.setPath(disk.getName());
+               newVol.setSize(disk.getVirtualSize());
+               return new CopyCmdAnswer(
+                               newVol);
+       } catch (CloudRuntimeException e) {
+               return new CopyCmdAnswer(e.toString()
+                               );
+       }
+    }
+
 }

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/68ffe1c7/plugins/hypervisors/vmware/src/com/cloud/storage/resource/VmwareStorageProcessor.java
----------------------------------------------------------------------
diff --git 
a/plugins/hypervisors/vmware/src/com/cloud/storage/resource/VmwareStorageProcessor.java
 
b/plugins/hypervisors/vmware/src/com/cloud/storage/resource/VmwareStorageProcessor.java
index 240c62f..16bfaf5 100644
--- 
a/plugins/hypervisors/vmware/src/com/cloud/storage/resource/VmwareStorageProcessor.java
+++ 
b/plugins/hypervisors/vmware/src/com/cloud/storage/resource/VmwareStorageProcessor.java
@@ -44,6 +44,7 @@ import org.apache.log4j.Logger;
 import com.cloud.agent.api.Answer;
 import com.cloud.agent.api.BackupSnapshotAnswer;
 import com.cloud.agent.api.Command;
+import com.cloud.agent.api.CreateVolumeFromSnapshotAnswer;
 import com.cloud.agent.api.ManageSnapshotAnswer;
 import com.cloud.agent.api.ManageSnapshotCommand;
 import com.cloud.agent.api.storage.CreatePrivateTemplateAnswer;
@@ -980,6 +981,7 @@ public class VmwareStorageProcessor implements 
StorageProcessor {
 
                                VolumeObjectTO newVol = new VolumeObjectTO();
                                newVol.setPath(volumeUuid);
+                               newVol.setSize(volume.getSize() / (1024L * 
1024L));
                                return new CreateObjectAnswer(newVol);
                        } finally {
                                s_logger.info("Destroy dummy VM after volume 
creation");
@@ -1154,4 +1156,120 @@ public class VmwareStorageProcessor implements 
StorageProcessor {
                        return new Answer(cmd, false, msg);
                }
        }
+       
+        private Long restoreVolumeFromSecStorage(VmwareHypervisorHost 
hyperHost, DatastoreMO primaryDsMo, String newVolumeName,
+                       String secStorageUrl, String secStorageDir, String 
backupName) throws Exception {
+
+                       String secondaryMountPoint = 
mountService.getMountPoint(secStorageUrl);
+                       String srcOVAFileName = secondaryMountPoint + "/" +  
secStorageDir + "/"
+                           + backupName + "." + 
ImageFormat.OVA.getFileExtension();
+                       String snapshotDir = "";
+                       if (backupName.contains("/")){
+                           snapshotDir = backupName.split("/")[0];
+                       }
+
+                       File ovafile = new File(srcOVAFileName);
+                       String srcOVFFileName = secondaryMountPoint + "/" +  
secStorageDir + "/"
+                               + backupName + ".ovf";
+                       File ovfFile = new File(srcOVFFileName);
+                       // String srcFileName = getOVFFilePath(srcOVAFileName);
+                       if (!ovfFile.exists()) {
+                           srcOVFFileName = getOVFFilePath(srcOVAFileName);
+                           if(srcOVFFileName == null && ovafile.exists() ) {  
// volss: ova file exists; o/w can't do tar
+                               Script command = new Script("tar", 0, s_logger);
+                               command.add("--no-same-owner");
+                               command.add("-xf", srcOVAFileName);
+                               command.setWorkDir(secondaryMountPoint + "/" +  
secStorageDir + "/" + snapshotDir);
+                               s_logger.info("Executing command: " + 
command.toString());
+                               String result = command.execute();
+                               if(result != null) {
+                                       String msg = "Unable to unpack snapshot 
OVA file at: " + srcOVAFileName;
+                                       s_logger.error(msg);
+                                       throw new Exception(msg);
+                               }
+                           } else {
+                              String msg = "Unable to find snapshot OVA file 
at: " + srcOVAFileName;
+                              s_logger.error(msg);
+                              throw new Exception(msg);
+                          }
+
+                          srcOVFFileName = getOVFFilePath(srcOVAFileName);
+                       }
+                       if(srcOVFFileName == null) {
+                           String msg = "Unable to locate OVF file in template 
package directory: " + srcOVAFileName;
+                           s_logger.error(msg);
+                           throw new Exception(msg);
+                       }
+
+                       VirtualMachineMO clonedVm = null;
+                       try {
+                           hyperHost.importVmFromOVF(srcOVFFileName, 
newVolumeName, primaryDsMo, "thin");
+                           clonedVm = 
hyperHost.findVmOnHyperHost(newVolumeName);
+                           if(clonedVm == null)
+                               throw new Exception("Unable to create container 
VM for volume creation");
+
+                           clonedVm.moveAllVmDiskFiles(primaryDsMo, "", false);
+                           clonedVm.detachAllDisks();
+                           return _storage.getSize(srcOVFFileName);
+                       } finally {
+                           if(clonedVm != null) {
+                               clonedVm.detachAllDisks();
+                               clonedVm.destroy();
+                           }
+                       }
+                   }
+
+       @Override
+       public Answer createVolumeFromSnapshot(CopyCommand cmd) {
+               DataTO srcData = cmd.getSrcTO();
+               SnapshotObjectTO snapshot = (SnapshotObjectTO)srcData;
+               DataTO destData = cmd.getDestTO();
+               PrimaryDataStoreTO pool = 
(PrimaryDataStoreTO)destData.getDataStore();
+               DataStoreTO imageStore = srcData.getDataStore();
+
+
+               if (!(imageStore instanceof NfsTO)) {
+                       return new CopyCmdAnswer("unsupported protocol");
+               }
+
+               NfsTO nfsImageStore = (NfsTO)imageStore;
+               String primaryStorageNameLabel = pool.getUuid();
+       
+        String secondaryStorageUrl = nfsImageStore.getUrl();
+               String backedUpSnapshotUuid = snapshot.getPath();
+               int index = backedUpSnapshotUuid.lastIndexOf(File.separator);
+               String backupPath = backedUpSnapshotUuid.substring(0, index);
+               backedUpSnapshotUuid = backedUpSnapshotUuid.substring(index + 
1);
+               String details = null;
+               String newVolumeName = 
UUID.randomUUID().toString().replaceAll("-", "");
+
+               VmwareContext context = hostService.getServiceContext(cmd);
+               try {
+                       VmwareHypervisorHost hyperHost = 
hostService.getHyperHost(context, cmd);
+                       ManagedObjectReference morPrimaryDs = 
HypervisorHostHelper.findDatastoreWithBackwardsCompatibility(hyperHost,
+                                       primaryStorageNameLabel);
+                       if (morPrimaryDs == null) {
+                               String msg = "Unable to find datastore: " + 
primaryStorageNameLabel;
+                               s_logger.error(msg);
+                               throw new Exception(msg);
+                       }
+
+                       DatastoreMO primaryDsMo = new 
DatastoreMO(hyperHost.getContext(), morPrimaryDs);
+                       Long size = restoreVolumeFromSecStorage(hyperHost, 
primaryDsMo,
+                                       newVolumeName, secondaryStorageUrl, 
backupPath, backedUpSnapshotUuid);
+
+                       VolumeObjectTO newVol = new VolumeObjectTO();
+                       newVol.setPath(newVolumeName);
+                       newVol.setSize(size);
+                       return new CopyCmdAnswer(newVol);
+               } catch (Throwable e) {
+                       if (e instanceof RemoteException) {
+                               hostService.invalidateServiceContext(context);
+                       }
+
+                       s_logger.error("Unexpecpted exception ", e);
+                       details = "CreateVolumeFromSnapshotCommand exception: " 
+ StringUtils.getExceptionStackInfo(e);
+               }
+               return new CopyCmdAnswer(details);
+       }
 }

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/68ffe1c7/plugins/hypervisors/xen/src/com/cloud/hypervisor/xen/resource/XenServerStorageProcessor.java
----------------------------------------------------------------------
diff --git 
a/plugins/hypervisors/xen/src/com/cloud/hypervisor/xen/resource/XenServerStorageProcessor.java
 
b/plugins/hypervisors/xen/src/com/cloud/hypervisor/xen/resource/XenServerStorageProcessor.java
index 03a2c28..0ef3519 100644
--- 
a/plugins/hypervisors/xen/src/com/cloud/hypervisor/xen/resource/XenServerStorageProcessor.java
+++ 
b/plugins/hypervisors/xen/src/com/cloud/hypervisor/xen/resource/XenServerStorageProcessor.java
@@ -55,6 +55,7 @@ import org.apache.xmlrpc.XmlRpcException;
 
 import com.cloud.agent.api.Answer;
 import com.cloud.agent.api.CreateStoragePoolCommand;
+import com.cloud.agent.api.CreateVolumeFromSnapshotAnswer;
 import com.cloud.agent.api.to.DataObjectType;
 import com.cloud.agent.api.to.DataStoreTO;
 import com.cloud.agent.api.to.DataTO;
@@ -1402,4 +1403,71 @@ public class XenServerStorageProcessor implements 
StorageProcessor {
         }
         return new CopyCmdAnswer(details);
     }
+
+       @Override
+       public Answer createVolumeFromSnapshot(CopyCommand cmd) {
+               Connection conn = this.hypervisorResource.getConnection();
+               DataTO srcData = cmd.getSrcTO();
+               SnapshotObjectTO snapshot = (SnapshotObjectTO)srcData;
+               DataTO destData = cmd.getDestTO();
+               PrimaryDataStoreTO pool = 
(PrimaryDataStoreTO)destData.getDataStore();
+               DataStoreTO imageStore = srcData.getDataStore();
+
+               if (!(imageStore instanceof NfsTO)) {
+                       return new CopyCmdAnswer("unsupported protocol");
+               }
+
+               NfsTO nfsImageStore = (NfsTO)imageStore;
+               String primaryStorageNameLabel = pool.getUuid();
+               String secondaryStorageUrl = nfsImageStore.getUrl();
+               int wait = cmd.getWait();
+               boolean result = false;
+               // Generic error message.
+               String details = null;
+               String volumeUUID = null;
+
+               if (secondaryStorageUrl == null) {
+                       details += " because the URL passed: " + 
secondaryStorageUrl + " is invalid.";
+                       return new CopyCmdAnswer(details);
+               }
+               try {
+                       SR primaryStorageSR = 
this.hypervisorResource.getSRByNameLabelandHost(conn, primaryStorageNameLabel);
+                       if (primaryStorageSR == null) {
+                               throw new InternalErrorException("Could not 
create volume from snapshot because the primary Storage SR could not be created 
from the name label: "
+                                               + primaryStorageNameLabel);
+                       }
+                       // Get the absolute path of the snapshot on the 
secondary storage.
+                       String snapshotInstallPath = snapshot.getPath();
+                       int index = 
snapshotInstallPath.lastIndexOf(File.separator);
+                       String snapshotName = 
snapshotInstallPath.substring(index + 1);
+               
+                       if (!snapshotName.startsWith("VHD-") && 
!snapshotName.endsWith(".vhd")) {
+                               snapshotInstallPath = snapshotInstallPath + 
".vhd";
+                       }
+                       URI snapshotURI = new URI(secondaryStorageUrl + 
File.separator + snapshotInstallPath);
+                       String snapshotPath = snapshotURI.getHost() + ":" + 
snapshotURI.getPath();
+                       String srUuid = primaryStorageSR.getUuid(conn);
+                       volumeUUID = copy_vhd_from_secondarystorage(conn, 
snapshotPath, srUuid, wait);
+                       result = true;
+                       VDI volume = VDI.getByUuid(conn, volumeUUID);
+                       VDI.Record vdir = volume.getRecord(conn);
+                       VolumeObjectTO newVol = new VolumeObjectTO();
+                       newVol.setPath(volumeUUID);
+                       newVol.setSize(vdir.virtualSize);
+                       return new CopyCmdAnswer(newVol);
+               } catch (XenAPIException e) {
+                       details += " due to " + e.toString();
+                       s_logger.warn(details, e);
+               } catch (Exception e) {
+                       details += " due to " + e.getMessage();
+                       s_logger.warn(details, e);
+               }
+               if (!result) {
+                       // Is this logged at a higher level?
+                       s_logger.error(details);
+               }
+
+               // In all cases return something.
+               return new CopyCmdAnswer(details);
+       }
 }

Reply via email to