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 8537a1cea26..c6b9b85c4a6 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 @@ -329,6 +329,10 @@ public class AncientDataMotionStrategy implements DataMotionStrategy { CopyCommand cmd = new CopyCommand(cacheData.getTO(), destData.getTO(), _copyvolumewait, _mgmtServer.getExecuteInSequence()); EndPoint ep = selector.select(cacheData, destData); Answer answer = ep.sendMessage(cmd); + // delete volume on cache store + if (cacheData != null) { + cacheMgr.deleteCacheObject(cacheData); + } return answer; } @@ -457,7 +461,7 @@ public class AncientDataMotionStrategy implements DataMotionStrategy { @Override public Void copyAsync(Map volumeMap, VirtualMachineTO vmTo, Host srcHost, Host destHost, - AsyncCompletionCallback callback) { + AsyncCompletionCallback callback) { CopyCommandResult result = new CopyCommandResult(null, null); result.setResult("Unsupported operation requested for copying data."); callback.complete(result); 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 e8fbf473579..f5af4bb4325 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 @@ -876,7 +876,7 @@ public class VolumeServiceImpl implements VolumeService { future.complete(res); } } catch (Exception e) { - s_logger.error("Failed to process copy volume callback", e); + s_logger.error("Failed to process migrate volume callback", e); res.setResult(e.toString()); future.complete(res); } 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 8bb11c05ea8..b0683d0ce15 100644 --- a/plugins/hypervisors/vmware/src/com/cloud/storage/resource/VmwareStorageProcessor.java +++ b/plugins/hypervisors/vmware/src/com/cloud/storage/resource/VmwareStorageProcessor.java @@ -11,7 +11,7 @@ // Unless required by applicable law or agreed to in writing, // software distributed under the License is distributed on an // "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY -// KIND, either express or implied. See the License for the +// KIND, either express or implied. See the License for the // specific language governing permissions and limitations // under the License. package com.cloud.storage.resource; @@ -27,6 +27,21 @@ import java.util.List; import java.util.Map; import java.util.UUID; +import org.apache.commons.lang.StringUtils; +import org.apache.log4j.Logger; + +import com.google.gson.Gson; +import com.vmware.vim25.ManagedObjectReference; +import com.vmware.vim25.VirtualDeviceConfigSpec; +import com.vmware.vim25.VirtualDeviceConfigSpecOperation; +import com.vmware.vim25.VirtualDisk; +import com.vmware.vim25.VirtualEthernetCard; +import com.vmware.vim25.VirtualLsiLogicController; +import com.vmware.vim25.VirtualMachineConfigSpec; +import com.vmware.vim25.VirtualMachineFileInfo; +import com.vmware.vim25.VirtualMachineGuestOsIdentifier; +import com.vmware.vim25.VirtualSCSISharing; + import org.apache.cloudstack.storage.command.AttachAnswer; import org.apache.cloudstack.storage.command.AttachCommand; import org.apache.cloudstack.storage.command.CopyCmdAnswer; @@ -39,8 +54,6 @@ import org.apache.cloudstack.storage.to.PrimaryDataStoreTO; import org.apache.cloudstack.storage.to.SnapshotObjectTO; import org.apache.cloudstack.storage.to.TemplateObjectTO; import org.apache.cloudstack.storage.to.VolumeObjectTO; -import org.apache.commons.lang.StringUtils; -import org.apache.log4j.Logger; import com.cloud.agent.api.Answer; import com.cloud.agent.api.Command; @@ -73,17 +86,6 @@ import com.cloud.utils.Pair; import com.cloud.utils.Ternary; import com.cloud.utils.script.Script; import com.cloud.vm.VirtualMachine.State; -import com.google.gson.Gson; -import com.vmware.vim25.ManagedObjectReference; -import com.vmware.vim25.VirtualDeviceConfigSpec; -import com.vmware.vim25.VirtualDeviceConfigSpecOperation; -import com.vmware.vim25.VirtualDisk; -import com.vmware.vim25.VirtualEthernetCard; -import com.vmware.vim25.VirtualLsiLogicController; -import com.vmware.vim25.VirtualMachineConfigSpec; -import com.vmware.vim25.VirtualMachineFileInfo; -import com.vmware.vim25.VirtualMachineGuestOsIdentifier; -import com.vmware.vim25.VirtualSCSISharing; public class VmwareStorageProcessor implements StorageProcessor { private static final Logger s_logger = Logger.getLogger(VmwareStorageProcessor.class); @@ -96,12 +98,12 @@ public class VmwareStorageProcessor implements StorageProcessor { private final Gson _gson; private final StorageLayer _storage = new JavaStorageLayer(); private final PremiumSecondaryStorageResource storageResource; - + public VmwareStorageProcessor(VmwareHostService hostService, boolean fullCloneFlag, VmwareStorageMount mountService, - Integer timeout, - VmwareResource resource, - Integer shutdownWaitMs, - PremiumSecondaryStorageResource storageResource) { + Integer timeout, + VmwareResource resource, + Integer shutdownWaitMs, + PremiumSecondaryStorageResource storageResource) { this.hostService = hostService; this._fullCloneFlag = fullCloneFlag; this.mountService = mountService; @@ -127,7 +129,7 @@ public class VmwareStorageProcessor implements StorageProcessor { return null; } private void copyTemplateFromSecondaryToPrimary(VmwareHypervisorHost hyperHost, DatastoreMO datastoreMo, String secondaryStorageUrl, - String templatePathAtSecondaryStorage, String templateName, String templateUuid) throws Exception { + String templatePathAtSecondaryStorage, String templateName, String templateUuid) throws Exception { s_logger.info("Executing copyTemplateFromSecondaryToPrimary. secondaryStorage: " + secondaryStorageUrl + ", templatePathAtSecondaryStorage: " + templatePathAtSecondaryStorage @@ -236,8 +238,9 @@ public class VmwareStorageProcessor implements StorageProcessor { VirtualMachineMO templateMo = VmwareHelper.pickOneVmOnRunningHost(dcMo.findVmByNameAndLabel(templateUuidName), true); if (templateMo == null) { - if(s_logger.isInfoEnabled()) + if(s_logger.isInfoEnabled()) { s_logger.info("Template " + templateName + " is not setup yet, setup template from secondary storage with uuid name: " + templateUuidName); + } ManagedObjectReference morDs = HypervisorHostHelper.findDatastoreWithBackwardsCompatibility(hyperHost, primaryStore.getUuid()); assert (morDs != null); DatastoreMO primaryStorageDatastoreMo = new DatastoreMO(context, morDs); @@ -263,7 +266,7 @@ public class VmwareStorageProcessor implements StorageProcessor { } } private boolean createVMLinkedClone(VirtualMachineMO vmTemplate, DatacenterMO dcMo, DatastoreMO dsMo, - String vmdkName, ManagedObjectReference morDatastore, ManagedObjectReference morPool) throws Exception { + String vmdkName, ManagedObjectReference morDatastore, ManagedObjectReference morPool) throws Exception { ManagedObjectReference morBaseSnapshot = vmTemplate.getSnapshotMor("cloud.template.base"); if (morBaseSnapshot == null) { @@ -272,8 +275,9 @@ public class VmwareStorageProcessor implements StorageProcessor { throw new Exception(msg); } - if(dsMo.folderExists(String.format("[%s]", dsMo.getName()), vmdkName)) + if(dsMo.folderExists(String.format("[%s]", dsMo.getName()), vmdkName)) { dsMo.deleteFile(String.format("[%s] %s/", dsMo.getName(), vmdkName), dcMo.getMor(), false); + } s_logger.info("creating linked clone from template"); if (!vmTemplate.createLinkedClone(vmdkName, morBaseSnapshot, dcMo.getVmFolder(), morPool, morDatastore)) { @@ -297,10 +301,11 @@ public class VmwareStorageProcessor implements StorageProcessor { } private boolean createVMFullClone(VirtualMachineMO vmTemplate, DatacenterMO dcMo, DatastoreMO dsMo, - String vmdkName, ManagedObjectReference morDatastore, ManagedObjectReference morPool) throws Exception { + String vmdkName, ManagedObjectReference morDatastore, ManagedObjectReference morPool) throws Exception { - if(dsMo.folderExists(String.format("[%s]", dsMo.getName()), vmdkName)) + if(dsMo.folderExists(String.format("[%s]", dsMo.getName()), vmdkName)) { dsMo.deleteFile(String.format("[%s] %s/", dsMo.getName(), vmdkName), dcMo.getMor(), false); + } s_logger.info("creating full clone from template"); if (!vmTemplate.createFullClone(vmdkName, dcMo.getVmFolder(), morPool, morDatastore)) { @@ -339,8 +344,9 @@ public class VmwareStorageProcessor implements StorageProcessor { DatacenterMO dcMo = new DatacenterMO(context, hyperHost.getHyperHostDatacenter()); VirtualMachineMO vmMo = null; ManagedObjectReference morDatastore = HypervisorHostHelper.findDatastoreWithBackwardsCompatibility(hyperHost, primaryStore.getUuid()); - if (morDatastore == null) + if (morDatastore == null) { throw new Exception("Unable to find datastore in vSphere"); + } DatastoreMO dsMo = new DatastoreMO(context, morDatastore); @@ -414,14 +420,14 @@ public class VmwareStorageProcessor implements StorageProcessor { this.hostService.invalidateServiceContext(null); } - String msg = "CreateCommand failed due to " + VmwareHelper.getExceptionMessage(e); + String msg = "CopyCommand failed due to " + VmwareHelper.getExceptionMessage(e); s_logger.error(msg, e); return new CopyCmdAnswer(e.toString()); } } private Pair copyVolumeFromSecStorage(VmwareHypervisorHost hyperHost, String srcVolumePath, - DatastoreMO dsMo, String secStorageUrl) throws Exception { + DatastoreMO dsMo, String secStorageUrl) throws Exception { String volumeFolder = null; String volumeName = null; @@ -509,8 +515,8 @@ public class VmwareStorageProcessor implements StorageProcessor { } private Pair copyVolumeToSecStorage(VmwareHostService hostService, VmwareHypervisorHost hyperHost, CopyCommand cmd, - String vmName, String poolId, String volumePath, String destVolumePath, - String secStorageUrl, String workerVmName) throws Exception { + String vmName, String poolId, String volumePath, String destVolumePath, + String secStorageUrl, String workerVmName) throws Exception { VirtualMachineMO workerVm=null; VirtualMachineMO vmMo=null; String exportName = UUID.randomUUID().toString(); @@ -611,7 +617,7 @@ public class VmwareStorageProcessor implements StorageProcessor { } private void postCreatePrivateTemplate(String installFullPath, long templateId, - String templateName, long size, long virtualSize) throws Exception { + String templateName, long size, long virtualSize) throws Exception { // TODO a bit ugly here BufferedWriter out = null; @@ -644,13 +650,14 @@ public class VmwareStorageProcessor implements StorageProcessor { out.write("ova.size=" + size); out.newLine(); } finally { - if(out != null) + if(out != null) { out.close(); + } } } private Ternary createTemplateFromVolume(VirtualMachineMO vmMo, String installPath, long templateId, String templateUniqueName, - String secStorageUrl, String volumePath, String workerVmName) throws Exception { + String secStorageUrl, String volumePath, String workerVmName) throws Exception { String secondaryMountPoint = mountService.getMountPoint(secStorageUrl); String installFullPath = secondaryMountPoint + "/" + installPath; @@ -736,8 +743,9 @@ public class VmwareStorageProcessor implements StorageProcessor { VirtualMachineMO vmMo = hyperHost.findVmOnHyperHost(volume.getVmName()); if (vmMo == null) { - if(s_logger.isDebugEnabled()) + if(s_logger.isDebugEnabled()) { s_logger.debug("Unable to find the owner VM for CreatePrivateTemplateFromVolumeCommand on host " + hyperHost.getHyperHostName() + ", try within datacenter"); + } vmMo = hyperHost.findVmOnPeerHyperHost(volume.getVmName()); if (vmMo == null) { @@ -779,7 +787,7 @@ public class VmwareStorageProcessor implements StorageProcessor { } private void writeMetaOvaForTemplate(String installFullPath, String ovfFilename, String vmdkFilename, - String templateName, long diskSize) throws Exception { + String templateName, long diskSize) throws Exception { // TODO a bit ugly here BufferedWriter out = null; @@ -798,13 +806,14 @@ public class VmwareStorageProcessor implements StorageProcessor { out.write("disk1.size=" + diskSize); out.newLine(); } finally { - if(out != null) + if(out != null) { out.close(); + } } } private Ternary createTemplateFromSnapshot(String installPath, String templateUniqueName, - String secStorageUrl, String snapshotPath, Long templateId) throws Exception { + String secStorageUrl, String snapshotPath, Long templateId) throws Exception { //Snapshot path is decoded in this form: /snapshots/account/volumeId/uuid/uuid String backupSSUuid; String snapshotFolder; @@ -955,7 +964,7 @@ public class VmwareStorageProcessor implements StorageProcessor { uniqeName, nfsSvr.getUrl(), snapshot.getPath(), template.getId() - ); + ); TemplateObjectTO newTemplate = new TemplateObjectTO(); newTemplate.setPath(result.first()); @@ -975,8 +984,8 @@ public class VmwareStorageProcessor implements StorageProcessor { } private void exportVolumeToSecondaryStroage(VirtualMachineMO vmMo, String volumePath, - String secStorageUrl, String secStorageDir, String exportName, - String workerVmName) throws Exception { + String secStorageUrl, String secStorageDir, String exportName, + String workerVmName) throws Exception { String secondaryMountPoint = mountService.getMountPoint(secStorageUrl); String exportPath = secondaryMountPoint + "/" + secStorageDir + "/" + exportName; @@ -986,8 +995,9 @@ public class VmwareStorageProcessor implements StorageProcessor { Script command = new Script(false, "mkdir", _timeout, s_logger); command.add("-p"); command.add(exportPath); - if(command.execute() != null) + if(command.execute() != null) { throw new Exception("unable to prepare snapshot backup directory"); + } } } @@ -1022,8 +1032,8 @@ public class VmwareStorageProcessor implements StorageProcessor { private String backupSnapshotToSecondaryStorage(VirtualMachineMO vmMo, String installPath, - String volumePath, String snapshotUuid, String secStorageUrl, - String prevSnapshotUuid, String prevBackupUuid, String workerVmName) throws Exception { + String volumePath, String snapshotUuid, String secStorageUrl, + String prevSnapshotUuid, String prevBackupUuid, String workerVmName) throws Exception { String backupUuid = UUID.randomUUID().toString(); exportVolumeToSecondaryStroage(vmMo, volumePath, secStorageUrl, @@ -1068,8 +1078,9 @@ public class VmwareStorageProcessor implements StorageProcessor { try { vmMo = hyperHost.findVmOnHyperHost(vmName); if (vmMo == null) { - if(s_logger.isDebugEnabled()) + if(s_logger.isDebugEnabled()) { s_logger.debug("Unable to find owner VM for BackupSnapshotCommand on host " + hyperHost.getHyperHostName() + ", will try within datacenter"); + } vmMo = hyperHost.findVmOnPeerHyperHost(vmName); if(vmMo == null) { @@ -1160,8 +1171,8 @@ public class VmwareStorageProcessor implements StorageProcessor { } private Answer attachVolume(Command cmd, DiskTO disk, boolean isAttach, boolean isManaged, String vmName, - String iScsiName, String storageHost, int storagePort, String initiatorUsername, String initiatorPassword, - String targetUsername, String targetPassword) { + String iScsiName, String storageHost, int storagePort, String initiatorUsername, String initiatorPassword, + String targetUsername, String targetPassword) { VolumeObjectTO volumeTO = (VolumeObjectTO)disk.getData(); PrimaryDataStoreTO primaryStore = (PrimaryDataStoreTO)volumeTO.getDataStore(); @@ -1231,8 +1242,9 @@ public class VmwareStorageProcessor implements StorageProcessor { VmwareHypervisorHost hyperHost = this.hostService.getHyperHost(this.hostService.getServiceContext(null), null); ManagedObjectReference morDatastore = hyperHost.mountDatastore(false, uri.getHost(), 0, uri.getPath(), storeName.replace("-", "")); - if (morDatastore == null) + if (morDatastore == null) { throw new Exception("Unable to mount secondary storage on host. storeUrl: " + storeUrl); + } return morDatastore; } @@ -1250,8 +1262,9 @@ public class VmwareStorageProcessor implements StorageProcessor { TemplateObjectTO iso = (TemplateObjectTO)disk.getData(); NfsTO nfsImageStore = (NfsTO)iso.getDataStore(); String storeUrl = null; - if (nfsImageStore != null) + if (nfsImageStore != null) { storeUrl = nfsImageStore.getUrl(); + } if (storeUrl == null) { if (!iso.getName().equalsIgnoreCase("vmware-tools.iso")) { String msg = "ISO store root url is not found in AttachIsoCommand"; @@ -1364,8 +1377,9 @@ public class VmwareStorageProcessor implements StorageProcessor { DatacenterMO dcMo = new DatacenterMO(context, hyperHost.getHyperHostDatacenter()); ManagedObjectReference morDatastore = HypervisorHostHelper.findDatastoreWithBackwardsCompatibility(hyperHost, primaryStore.getUuid()); - if (morDatastore == null) + if (morDatastore == null) { throw new Exception("Unable to find datastore in vSphere"); + } DatastoreMO dsMo = new DatastoreMO(context, morDatastore); // create data volume @@ -1425,17 +1439,17 @@ public class VmwareStorageProcessor implements StorageProcessor { s_logger.info("Executing resource DestroyCommand: " + _gson.toJson(cmd)); } - /* - * DestroyCommand content example - * - * {"volume": {"id":5,"name":"Volume1", "mountPoint":"/export/home/kelven/vmware-test/primary", - * "path":"6bb8762f-c34c-453c-8e03-26cc246ceec4", "size":0,"type":"DATADISK","resourceType": - * "STORAGE_POOL","storagePoolType":"NetworkFilesystem", "poolId":0,"deviceId":0 } } - * - * {"volume": {"id":1, "name":"i-2-1-KY-ROOT", "mountPoint":"/export/home/kelven/vmware-test/primary", - * "path":"i-2-1-KY-ROOT","size":0,"type":"ROOT", "resourceType":"STORAGE_POOL", "storagePoolType":"NetworkFilesystem", - * "poolId":0,"deviceId":0 } } - */ + /* + * DestroyCommand content example + * + * {"volume": {"id":5,"name":"Volume1", "mountPoint":"/export/home/kelven/vmware-test/primary", + * "path":"6bb8762f-c34c-453c-8e03-26cc246ceec4", "size":0,"type":"DATADISK","resourceType": + * "STORAGE_POOL","storagePoolType":"NetworkFilesystem", "poolId":0,"deviceId":0 } } + * + * {"volume": {"id":1, "name":"i-2-1-KY-ROOT", "mountPoint":"/export/home/kelven/vmware-test/primary", + * "path":"i-2-1-KY-ROOT","size":0,"type":"ROOT", "resourceType":"STORAGE_POOL", "storagePoolType":"NetworkFilesystem", + * "poolId":0,"deviceId":0 } } + */ try { VmwareContext context = this.hostService.getServiceContext(null); @@ -1469,8 +1483,9 @@ public class VmwareStorageProcessor implements StorageProcessor { List networks = vmMo.getNetworksWithDetails(); // tear down all devices first before we destroy the VM to avoid accidently delete disk backing files - if (this.resource.getVmState(vmMo) != State.Stopped) + if (this.resource.getVmState(vmMo) != State.Stopped) { vmMo.safePowerOff(_shutdown_waitMs); + } vmMo.tearDownDevices(new Class[] { VirtualDisk.class, VirtualEthernetCard.class }); vmMo.destroy(); @@ -1483,8 +1498,9 @@ public class VmwareStorageProcessor implements StorageProcessor { } } - if (s_logger.isInfoEnabled()) + if (s_logger.isInfoEnabled()) { s_logger.info("Destroy volume by original name: " + vol.getPath() + ".vmdk"); + } dsMo.deleteFile(vol.getPath() + ".vmdk", morDc, true); // root volume may be created via linked-clone, delete the delta disk as well @@ -1509,8 +1525,9 @@ public class VmwareStorageProcessor implements StorageProcessor { // evitTemplate will be converted into DestroyCommand, test if we are running in this case VirtualMachineMO vmMo = clusterMo.findVmOnHyperHost(vol.getPath()); if (vmMo != null) { - if (s_logger.isInfoEnabled()) + if (s_logger.isInfoEnabled()) { s_logger.info("Destroy template volume " + vol.getPath()); + } vmMo.destroy(); return new Answer(cmd, true, "Success"); @@ -1566,7 +1583,7 @@ public class VmwareStorageProcessor implements StorageProcessor { } private Long restoreVolumeFromSecStorage(VmwareHypervisorHost hyperHost, DatastoreMO primaryDsMo, String newVolumeName, - String secStorageUrl, String secStorageDir, String backupName) throws Exception { + String secStorageUrl, String secStorageDir, String backupName) throws Exception { String secondaryMountPoint = mountService.getMountPoint(secStorageUrl); String srcOVAFileName = null; @@ -1617,8 +1634,9 @@ public class VmwareStorageProcessor implements StorageProcessor { try { hyperHost.importVmFromOVF(srcOVFFileName, newVolumeName, primaryDsMo, "thin"); clonedVm = hyperHost.findVmOnHyperHost(newVolumeName); - if(clonedVm == null) + if(clonedVm == null) { throw new Exception("Unable to create container VM for volume creation"); + } clonedVm.moveAllVmDiskFiles(primaryDsMo, "", false); clonedVm.detachAllDisks();