Search in sources :

Example 31 with SnapshotObjectTO

use of org.apache.cloudstack.storage.to.SnapshotObjectTO in project cloudstack by apache.

the class Xenserver625StorageProcessor method backupSnapshot.

@Override
public Answer backupSnapshot(final CopyCommand cmd) {
    final Connection conn = hypervisorResource.getConnection();
    final DataTO srcData = cmd.getSrcTO();
    final DataTO cacheData = cmd.getCacheTO();
    final DataTO destData = cmd.getDestTO();
    final int wait = cmd.getWait();
    final PrimaryDataStoreTO primaryStore = (PrimaryDataStoreTO) srcData.getDataStore();
    final String primaryStorageNameLabel = primaryStore.getUuid();
    String secondaryStorageUrl = null;
    NfsTO cacheStore = null;
    String destPath = null;
    if (cacheData != null) {
        cacheStore = (NfsTO) cacheData.getDataStore();
        secondaryStorageUrl = cacheStore.getUrl();
        destPath = cacheData.getPath();
    } else {
        cacheStore = (NfsTO) destData.getDataStore();
        secondaryStorageUrl = cacheStore.getUrl();
        destPath = destData.getPath();
    }
    final SnapshotObjectTO snapshotTO = (SnapshotObjectTO) srcData;
    final SnapshotObjectTO snapshotOnImage = (SnapshotObjectTO) destData;
    String snapshotUuid = snapshotTO.getPath();
    final String prevBackupUuid = snapshotOnImage.getParentSnapshotPath();
    final String prevSnapshotUuid = snapshotTO.getParentSnapshotPath();
    final Map<String, String> options = cmd.getOptions();
    // By default assume failure
    String details = null;
    String snapshotBackupUuid = null;
    boolean fullbackup = Boolean.parseBoolean(options.get("fullSnapshot"));
    Long physicalSize = null;
    try {
        SR primaryStorageSR = null;
        if (primaryStore.isManaged()) {
            // currently, managed storage only supports full backup
            fullbackup = true;
            final Map<String, String> srcDetails = cmd.getOptions();
            final String iScsiName = srcDetails.get(DiskTO.IQN);
            final String storageHost = srcDetails.get(DiskTO.STORAGE_HOST);
            final String chapInitiatorUsername = srcDetails.get(DiskTO.CHAP_INITIATOR_USERNAME);
            final String chapInitiatorSecret = srcDetails.get(DiskTO.CHAP_INITIATOR_SECRET);
            final String srType = CitrixResourceBase.SRType.LVMOISCSI.toString();
            primaryStorageSR = hypervisorResource.getIscsiSR(conn, iScsiName, storageHost, iScsiName, chapInitiatorUsername, chapInitiatorSecret, false, srType, true);
            final VDI srcVdi = primaryStorageSR.getVDIs(conn).iterator().next();
            if (srcVdi == null) {
                throw new InternalErrorException("Could not Find a VDI on the SR: " + primaryStorageSR.getNameLabel(conn));
            }
            snapshotUuid = srcVdi.getUuid(conn);
        } else {
            primaryStorageSR = hypervisorResource.getSRByNameLabelandHost(conn, primaryStorageNameLabel);
        }
        if (primaryStorageSR == null) {
            throw new InternalErrorException("Could not backup snapshot because the primary Storage SR could not be created from the name label: " + primaryStorageNameLabel);
        }
        // String psUuid = primaryStorageSR.getUuid(conn);
        final Boolean isISCSI = IsISCSI(primaryStorageSR.getType(conn));
        final VDI snapshotVdi = getVDIbyUuid(conn, snapshotUuid);
        final String snapshotPaUuid = snapshotVdi.getUuid(conn);
        final URI uri = new URI(secondaryStorageUrl);
        final String secondaryStorageMountPath = uri.getHost() + ":" + uri.getPath();
        final DataStoreTO destStore = destData.getDataStore();
        final String folder = destPath;
        String finalPath = null;
        final String localMountPoint = BaseMountPointOnHost + File.separator + UUID.nameUUIDFromBytes(secondaryStorageUrl.getBytes()).toString();
        if (fullbackup) {
            SR snapshotSr = null;
            Task task = null;
            try {
                final String localDir = "/var/cloud_mount/" + UUID.nameUUIDFromBytes(secondaryStorageMountPath.getBytes());
                mountNfs(conn, secondaryStorageMountPath, localDir);
                final boolean result = makeDirectory(conn, localDir + "/" + folder);
                if (!result) {
                    details = " Filed to create folder " + folder + " in secondary storage";
                    s_logger.warn(details);
                    return new CopyCmdAnswer(details);
                }
                snapshotSr = createFileSr(conn, secondaryStorageMountPath, folder);
                task = snapshotVdi.copyAsync(conn, snapshotSr, null, null);
                // poll every 1 seconds ,
                hypervisorResource.waitForTask(conn, task, 1000, wait * 1000);
                hypervisorResource.checkForSuccess(conn, task);
                final VDI backedVdi = Types.toVDI(task, conn);
                snapshotBackupUuid = backedVdi.getUuid(conn);
                physicalSize = backedVdi.getPhysicalUtilisation(conn);
                if (destStore instanceof SwiftTO) {
                    try {
                        final String container = "S-" + snapshotTO.getVolume().getVolumeId().toString();
                        final String destSnapshotName = swiftBackupSnapshot(conn, (SwiftTO) destStore, snapshotSr.getUuid(conn), snapshotBackupUuid, container, false, wait);
                        final String swiftPath = container + File.separator + destSnapshotName;
                        finalPath = swiftPath;
                    } finally {
                        try {
                            deleteSnapshotBackup(conn, localMountPoint, folder, secondaryStorageMountPath, snapshotBackupUuid);
                        } catch (final Exception e) {
                            s_logger.debug("Failed to delete snapshot on cache storages", e);
                        }
                    }
                } else if (destStore instanceof S3TO) {
                    try {
                        finalPath = backupSnapshotToS3(conn, (S3TO) destStore, snapshotSr.getUuid(conn), folder, snapshotBackupUuid, isISCSI, wait);
                        if (finalPath == null) {
                            throw new CloudRuntimeException("S3 upload of snapshots " + snapshotBackupUuid + " failed");
                        }
                    } finally {
                        try {
                            deleteSnapshotBackup(conn, localMountPoint, folder, secondaryStorageMountPath, snapshotBackupUuid);
                        } catch (final Exception e) {
                            s_logger.debug("Failed to delete snapshot on cache storages", e);
                        }
                    }
                // finalPath = folder + File.separator +
                // snapshotBackupUuid;
                } else {
                    finalPath = folder + File.separator + snapshotBackupUuid + ".vhd";
                }
            } finally {
                if (task != null) {
                    try {
                        task.destroy(conn);
                    } catch (final Exception e) {
                        s_logger.warn("unable to destroy task(" + task.toWireString() + ") due to " + e.toString());
                    }
                }
                if (snapshotSr != null) {
                    hypervisorResource.removeSR(conn, snapshotSr);
                }
                if (primaryStore.isManaged()) {
                    hypervisorResource.removeSR(conn, primaryStorageSR);
                }
            }
        } else {
            final String primaryStorageSRUuid = primaryStorageSR.getUuid(conn);
            if (destStore instanceof SwiftTO) {
                final String container = "S-" + snapshotTO.getVolume().getVolumeId().toString();
                snapshotBackupUuid = swiftBackupSnapshot(conn, (SwiftTO) destStore, primaryStorageSRUuid, snapshotPaUuid, "S-" + snapshotTO.getVolume().getVolumeId().toString(), isISCSI, wait);
                finalPath = container + File.separator + snapshotBackupUuid;
            } else if (destStore instanceof S3TO) {
                finalPath = backupSnapshotToS3(conn, (S3TO) destStore, primaryStorageSRUuid, folder, snapshotPaUuid, isISCSI, wait);
                if (finalPath == null) {
                    throw new CloudRuntimeException("S3 upload of snapshots " + snapshotPaUuid + " failed");
                }
            } else {
                final String result = backupSnapshot(conn, primaryStorageSRUuid, localMountPoint, folder, secondaryStorageMountPath, snapshotUuid, prevBackupUuid, prevSnapshotUuid, isISCSI, wait);
                final String[] tmp = result.split("#");
                snapshotBackupUuid = tmp[0];
                physicalSize = Long.parseLong(tmp[1]);
                finalPath = folder + File.separator + snapshotBackupUuid + ".vhd";
            }
            final String volumeUuid = snapshotTO.getVolume().getPath();
            destroySnapshotOnPrimaryStorageExceptThis(conn, volumeUuid, snapshotUuid);
        }
        final SnapshotObjectTO newSnapshot = new SnapshotObjectTO();
        newSnapshot.setPath(finalPath);
        newSnapshot.setPhysicalSize(physicalSize);
        if (fullbackup) {
            newSnapshot.setParentSnapshotPath(null);
        } else {
            newSnapshot.setParentSnapshotPath(prevBackupUuid);
        }
        return new CopyCmdAnswer(newSnapshot);
    } catch (final Types.XenAPIException e) {
        details = "BackupSnapshot Failed due to " + e.toString();
        s_logger.warn(details, e);
    } catch (final Exception e) {
        details = "BackupSnapshot Failed due to " + e.getMessage();
        s_logger.warn(details, e);
    }
    return new CopyCmdAnswer(details);
}
Also used : SnapshotObjectTO(org.apache.cloudstack.storage.to.SnapshotObjectTO) Types(com.xensource.xenapi.Types) DataStoreTO(com.cloud.agent.api.to.DataStoreTO) PrimaryDataStoreTO(org.apache.cloudstack.storage.to.PrimaryDataStoreTO) Task(com.xensource.xenapi.Task) SwiftTO(com.cloud.agent.api.to.SwiftTO) Connection(com.xensource.xenapi.Connection) InternalErrorException(com.cloud.exception.InternalErrorException) NfsTO(com.cloud.agent.api.to.NfsTO) URI(java.net.URI) XenAPIException(com.xensource.xenapi.Types.XenAPIException) InternalErrorException(com.cloud.exception.InternalErrorException) XmlRpcException(org.apache.xmlrpc.XmlRpcException) CloudRuntimeException(com.cloud.utils.exception.CloudRuntimeException) XenAPIException(com.xensource.xenapi.Types.XenAPIException) DataTO(com.cloud.agent.api.to.DataTO) PrimaryDataStoreTO(org.apache.cloudstack.storage.to.PrimaryDataStoreTO) CloudRuntimeException(com.cloud.utils.exception.CloudRuntimeException) VDI(com.xensource.xenapi.VDI) S3TO(com.cloud.agent.api.to.S3TO) CopyCmdAnswer(org.apache.cloudstack.storage.command.CopyCmdAnswer) SR(com.xensource.xenapi.SR)

Example 32 with SnapshotObjectTO

use of org.apache.cloudstack.storage.to.SnapshotObjectTO in project cloudstack by apache.

the class NfsSecondaryStorageResource method postProcessing.

protected CopyCmdAnswer postProcessing(File destFile, String downloadPath, String destPath, DataTO srcData, DataTO destData) throws ConfigurationException {
    if (destData.getObjectType() == DataObjectType.SNAPSHOT) {
        SnapshotObjectTO snapshot = new SnapshotObjectTO();
        snapshot.setPath(destPath + File.separator + destFile.getName());
        CopyCmdAnswer answer = new CopyCmdAnswer(snapshot);
        return answer;
    }
    // do post processing to unzip the file if it is compressed
    String scriptsDir = "scripts/storage/secondary";
    String createTmpltScr = Script.findScript(scriptsDir, "createtmplt.sh");
    if (createTmpltScr == null) {
        throw new ConfigurationException("Unable to find createtmplt.sh");
    }
    s_logger.info("createtmplt.sh found in " + createTmpltScr);
    String createVolScr = Script.findScript(scriptsDir, "createvolume.sh");
    if (createVolScr == null) {
        throw new ConfigurationException("Unable to find createvolume.sh");
    }
    s_logger.info("createvolume.sh found in " + createVolScr);
    String script = srcData.getObjectType() == DataObjectType.TEMPLATE ? createTmpltScr : createVolScr;
    int installTimeoutPerGig = 180 * 60 * 1000;
    long imgSizeGigs = (long) Math.ceil(destFile.length() * 1.0d / (1024 * 1024 * 1024));
    // add one just in case
    imgSizeGigs++;
    long timeout = imgSizeGigs * installTimeoutPerGig;
    String origPath = destFile.getAbsolutePath();
    String extension = null;
    if (srcData.getObjectType() == DataObjectType.TEMPLATE) {
        extension = ((TemplateObjectTO) srcData).getFormat().getFileExtension();
    } else if (srcData.getObjectType() == DataObjectType.VOLUME) {
        extension = ((VolumeObjectTO) srcData).getFormat().getFileExtension();
    }
    String templateName = UUID.randomUUID().toString();
    String templateFilename = templateName + "." + extension;
    Script scr = new Script(script, timeout, s_logger);
    // not used for now
    scr.add("-s", Long.toString(imgSizeGigs));
    scr.add("-n", templateFilename);
    scr.add("-t", downloadPath);
    // this is the temporary
    scr.add("-f", origPath);
    // template file downloaded
    String result;
    result = scr.execute();
    if (result != null) {
        // script execution failure
        throw new CloudRuntimeException("Failed to run script " + script);
    }
    String finalFileName = templateFilename;
    String finalDownloadPath = destPath + File.separator + templateFilename;
    // compute the size of
    long size = _storage.getSize(downloadPath + File.separator + templateFilename);
    DataTO newDestTO = null;
    if (destData.getObjectType() == DataObjectType.TEMPLATE) {
        TemplateObjectTO newTemplTO = new TemplateObjectTO();
        newTemplTO.setPath(finalDownloadPath);
        newTemplTO.setName(finalFileName);
        newTemplTO.setSize(size);
        newTemplTO.setPhysicalSize(size);
        newDestTO = newTemplTO;
    } else {
        VolumeObjectTO newVolTO = new VolumeObjectTO();
        newVolTO.setPath(finalDownloadPath);
        newVolTO.setName(finalFileName);
        newVolTO.setSize(size);
        newDestTO = newVolTO;
    }
    return new CopyCmdAnswer(newDestTO);
}
Also used : SnapshotObjectTO(org.apache.cloudstack.storage.to.SnapshotObjectTO) Script(com.cloud.utils.script.Script) DataTO(com.cloud.agent.api.to.DataTO) ConfigurationException(javax.naming.ConfigurationException) CloudRuntimeException(com.cloud.utils.exception.CloudRuntimeException) VolumeObjectTO(org.apache.cloudstack.storage.to.VolumeObjectTO) TemplateObjectTO(org.apache.cloudstack.storage.to.TemplateObjectTO) CopyCmdAnswer(org.apache.cloudstack.storage.command.CopyCmdAnswer)

Example 33 with SnapshotObjectTO

use of org.apache.cloudstack.storage.to.SnapshotObjectTO in project cloudstack by apache.

the class NfsSecondaryStorageResource method createTemplateFromSnapshot.

protected Answer createTemplateFromSnapshot(CopyCommand cmd) {
    DataTO srcData = cmd.getSrcTO();
    DataTO destData = cmd.getDestTO();
    DataStoreTO srcDataStore = srcData.getDataStore();
    DataStoreTO destDataStore = destData.getDataStore();
    if (srcDataStore.getRole() == DataStoreRole.Image || srcDataStore.getRole() == DataStoreRole.ImageCache || srcDataStore.getRole() == DataStoreRole.Primary) {
        if (!(srcDataStore instanceof NfsTO)) {
            s_logger.debug("only support nfs storage as src, when create template from snapshot");
            return Answer.createUnsupportedCommandAnswer(cmd);
        }
        if (destDataStore instanceof NfsTO) {
            return copySnapshotToTemplateFromNfsToNfs(cmd, (SnapshotObjectTO) srcData, (NfsTO) srcDataStore, (TemplateObjectTO) destData, (NfsTO) destDataStore);
        } else if (destDataStore instanceof SwiftTO) {
            //create template on the same data store
            CopyCmdAnswer answer = (CopyCmdAnswer) copySnapshotToTemplateFromNfsToNfs(cmd, (SnapshotObjectTO) srcData, (NfsTO) srcDataStore, (TemplateObjectTO) destData, (NfsTO) srcDataStore);
            if (!answer.getResult()) {
                return answer;
            }
            s_logger.debug("starting copy template to swift");
            TemplateObjectTO newTemplate = (TemplateObjectTO) answer.getNewData();
            newTemplate.setDataStore(srcDataStore);
            CopyCommand newCpyCmd = new CopyCommand(newTemplate, destData, cmd.getWait(), cmd.executeInSequence());
            Answer result = copyFromNfsToSwift(newCpyCmd);
            cleanupStagingNfs(newTemplate);
            return result;
        } else if (destDataStore instanceof S3TO) {
            //create template on the same data store
            CopyCmdAnswer answer = (CopyCmdAnswer) copySnapshotToTemplateFromNfsToNfs(cmd, (SnapshotObjectTO) srcData, (NfsTO) srcDataStore, (TemplateObjectTO) destData, (NfsTO) srcDataStore);
            if (!answer.getResult()) {
                return answer;
            }
            TemplateObjectTO newTemplate = (TemplateObjectTO) answer.getNewData();
            newTemplate.setDataStore(srcDataStore);
            CopyCommand newCpyCmd = new CopyCommand(newTemplate, destData, cmd.getWait(), cmd.executeInSequence());
            Answer result = copyFromNfsToS3(newCpyCmd);
            cleanupStagingNfs(newTemplate);
            return result;
        }
    }
    s_logger.debug("Failed to create template from snapshot");
    return new CopyCmdAnswer("Unsupported protocol");
}
Also used : SnapshotObjectTO(org.apache.cloudstack.storage.to.SnapshotObjectTO) ListTemplateAnswer(com.cloud.agent.api.storage.ListTemplateAnswer) UploadStatusAnswer(org.apache.cloudstack.storage.command.UploadStatusAnswer) GetStorageStatsAnswer(com.cloud.agent.api.GetStorageStatsAnswer) CopyCmdAnswer(org.apache.cloudstack.storage.command.CopyCmdAnswer) ListVolumeAnswer(com.cloud.agent.api.storage.ListVolumeAnswer) DownloadAnswer(com.cloud.agent.api.storage.DownloadAnswer) Answer(com.cloud.agent.api.Answer) CheckHealthAnswer(com.cloud.agent.api.CheckHealthAnswer) ReadyAnswer(com.cloud.agent.api.ReadyAnswer) SecStorageSetupAnswer(com.cloud.agent.api.SecStorageSetupAnswer) DataStoreTO(com.cloud.agent.api.to.DataStoreTO) DataTO(com.cloud.agent.api.to.DataTO) SwiftTO(com.cloud.agent.api.to.SwiftTO) CopyCommand(org.apache.cloudstack.storage.command.CopyCommand) TemplateObjectTO(org.apache.cloudstack.storage.to.TemplateObjectTO) NfsTO(com.cloud.agent.api.to.NfsTO) S3TO(com.cloud.agent.api.to.S3TO) CopyCmdAnswer(org.apache.cloudstack.storage.command.CopyCmdAnswer)

Example 34 with SnapshotObjectTO

use of org.apache.cloudstack.storage.to.SnapshotObjectTO in project cloudstack by apache.

the class NfsSecondaryStorageResource method copyFromNfsToSwift.

/**
     * Copies data from NFS and uploads it into a Swift container
     *
     * @param cmd CopyComand
     * @return CopyCmdAnswer
     */
protected Answer copyFromNfsToSwift(CopyCommand cmd) {
    final DataTO srcData = cmd.getSrcTO();
    final DataTO destData = cmd.getDestTO();
    DataStoreTO srcDataStore = srcData.getDataStore();
    NfsTO srcStore = (NfsTO) srcDataStore;
    DataStoreTO destDataStore = destData.getDataStore();
    File srcFile = getFile(srcData.getPath(), srcStore.getUrl(), _nfsVersion);
    SwiftTO swift = (SwiftTO) destDataStore;
    long pathId = destData.getId();
    try {
        if (destData instanceof SnapshotObjectTO) {
            pathId = ((SnapshotObjectTO) destData).getVolume().getId();
        }
        String containerName = SwiftUtil.getContainerName(destData.getObjectType().toString(), pathId);
        String swiftPath = SwiftUtil.putObject(swift, srcFile, containerName, srcFile.getName());
        DataTO retObj = null;
        if (destData.getObjectType() == DataObjectType.TEMPLATE) {
            TemplateObjectTO destTemplateData = (TemplateObjectTO) destData;
            String uniqueName = destTemplateData.getName();
            swiftUploadMetadataFile(swift, srcFile, containerName, uniqueName);
            TemplateObjectTO newTemplate = new TemplateObjectTO();
            newTemplate.setPath(swiftPath);
            newTemplate.setSize(getVirtualSize(srcFile, getTemplateFormat(srcFile.getName())));
            newTemplate.setPhysicalSize(srcFile.length());
            newTemplate.setFormat(getTemplateFormat(srcFile.getName()));
            retObj = newTemplate;
        } else if (destData.getObjectType() == DataObjectType.VOLUME) {
            VolumeObjectTO newVol = new VolumeObjectTO();
            newVol.setPath(containerName);
            newVol.setSize(getVirtualSize(srcFile, getTemplateFormat(srcFile.getName())));
            retObj = newVol;
        } else if (destData.getObjectType() == DataObjectType.SNAPSHOT) {
            SnapshotObjectTO newSnapshot = new SnapshotObjectTO();
            newSnapshot.setPath(containerName + File.separator + srcFile.getName());
            retObj = newSnapshot;
        }
        return new CopyCmdAnswer(retObj);
    } catch (Exception e) {
        s_logger.error("failed to upload " + srcData.getPath(), e);
        return new CopyCmdAnswer("failed to upload " + srcData.getPath() + e.toString());
    }
}
Also used : SnapshotObjectTO(org.apache.cloudstack.storage.to.SnapshotObjectTO) DataStoreTO(com.cloud.agent.api.to.DataStoreTO) DataTO(com.cloud.agent.api.to.DataTO) SwiftTO(com.cloud.agent.api.to.SwiftTO) VolumeObjectTO(org.apache.cloudstack.storage.to.VolumeObjectTO) TemplateObjectTO(org.apache.cloudstack.storage.to.TemplateObjectTO) NfsTO(com.cloud.agent.api.to.NfsTO) File(java.io.File) S3Utils.putFile(com.cloud.utils.storage.S3.S3Utils.putFile) CopyCmdAnswer(org.apache.cloudstack.storage.command.CopyCmdAnswer) NoSuchAlgorithmException(java.security.NoSuchAlgorithmException) CloudRuntimeException(com.cloud.utils.exception.CloudRuntimeException) IOException(java.io.IOException) UnknownHostException(java.net.UnknownHostException) InvalidParameterValueException(com.cloud.exception.InvalidParameterValueException) UnsupportedEncodingException(java.io.UnsupportedEncodingException) InternalErrorException(com.cloud.exception.InternalErrorException) ConfigurationException(javax.naming.ConfigurationException)

Example 35 with SnapshotObjectTO

use of org.apache.cloudstack.storage.to.SnapshotObjectTO in project cloudstack by apache.

the class VmwareStorageProcessor method backupSnapshot.

@Override
public Answer backupSnapshot(CopyCommand cmd) {
    SnapshotObjectTO srcSnapshot = (SnapshotObjectTO) cmd.getSrcTO();
    DataStoreTO primaryStore = srcSnapshot.getDataStore();
    SnapshotObjectTO destSnapshot = (SnapshotObjectTO) cmd.getDestTO();
    DataStoreTO destStore = destSnapshot.getDataStore();
    if (!(destStore instanceof NfsTO)) {
        return new CopyCmdAnswer("unsupported protocol");
    }
    NfsTO destNfsStore = (NfsTO) destStore;
    String secondaryStorageUrl = destNfsStore.getUrl();
    String snapshotUuid = srcSnapshot.getPath();
    String prevSnapshotUuid = srcSnapshot.getParentSnapshotPath();
    String prevBackupUuid = destSnapshot.getParentSnapshotPath();
    VirtualMachineMO workerVm = null;
    String workerVMName = null;
    String volumePath = srcSnapshot.getVolume().getPath();
    ManagedObjectReference morDs = null;
    DatastoreMO dsMo = null;
    // By default assume failure
    String details = null;
    boolean success = false;
    String snapshotBackupUuid = null;
    boolean hasOwnerVm = false;
    Ternary<String, String, String[]> backupResult = null;
    VmwareContext context = hostService.getServiceContext(cmd);
    VirtualMachineMO vmMo = null;
    String vmName = srcSnapshot.getVmName();
    try {
        VmwareHypervisorHost hyperHost = hostService.getHyperHost(context, cmd);
        morDs = HypervisorHostHelper.findDatastoreWithBackwardsCompatibility(hyperHost, primaryStore.getUuid());
        CopyCmdAnswer answer = null;
        try {
            if (vmName != null) {
                vmMo = hyperHost.findVmOnHyperHost(vmName);
                if (vmMo == null) {
                    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) {
                dsMo = new DatastoreMO(hyperHost.getContext(), morDs);
                workerVMName = hostService.getWorkerName(context, cmd, 0);
                vmMo = HypervisorHostHelper.createWorkerVM(hyperHost, dsMo, workerVMName);
                if (vmMo == null) {
                    throw new Exception("Failed to find the newly create or relocated VM. vmName: " + workerVMName);
                }
                workerVm = vmMo;
                // attach volume to worker VM
                String datastoreVolumePath = dsMo.getDatastorePath(volumePath + ".vmdk");
                vmMo.attachDisk(new String[] { datastoreVolumePath }, morDs);
            } else {
                s_logger.info("Using owner VM " + vmName + " for snapshot operation");
                hasOwnerVm = true;
            }
            if (!vmMo.createSnapshot(snapshotUuid, "Snapshot taken for " + srcSnapshot.getName(), false, false)) {
                throw new Exception("Failed to take snapshot " + srcSnapshot.getName() + " on vm: " + vmName);
            }
            backupResult = backupSnapshotToSecondaryStorage(vmMo, destSnapshot.getPath(), srcSnapshot.getVolume().getPath(), snapshotUuid, secondaryStorageUrl, prevSnapshotUuid, prevBackupUuid, hostService.getWorkerName(context, cmd, 1), _nfsVersion);
            snapshotBackupUuid = backupResult.first();
            success = (snapshotBackupUuid != null);
            if (!success) {
                details = "Failed to backUp the snapshot with uuid: " + snapshotUuid + " to secondary storage.";
                answer = new CopyCmdAnswer(details);
            } else {
                details = "Successfully backedUp the snapshot with Uuid: " + snapshotUuid + " to secondary storage.";
                // Get snapshot physical size
                long physicalSize = 0l;
                String secondaryMountPoint = mountService.getMountPoint(secondaryStorageUrl, _nfsVersion);
                String snapshotDir = destSnapshot.getPath() + "/" + snapshotBackupUuid;
                File[] files = new File(secondaryMountPoint + "/" + snapshotDir).listFiles();
                if (files != null) {
                    for (File file : files) {
                        String fileName = file.getName();
                        if (fileName.toLowerCase().startsWith(snapshotBackupUuid) && fileName.toLowerCase().endsWith(".vmdk")) {
                            physicalSize = new File(secondaryMountPoint + "/" + snapshotDir + "/" + fileName).length();
                            break;
                        }
                    }
                }
                SnapshotObjectTO newSnapshot = new SnapshotObjectTO();
                newSnapshot.setPath(snapshotDir + "/" + snapshotBackupUuid);
                newSnapshot.setPhysicalSize(physicalSize);
                answer = new CopyCmdAnswer(newSnapshot);
            }
        } finally {
            if (vmMo != null) {
                ManagedObjectReference snapshotMor = vmMo.getSnapshotMor(snapshotUuid);
                if (snapshotMor != null) {
                    vmMo.removeSnapshot(snapshotUuid, false);
                    // in the middle
                    if (backupResult != null && hasOwnerVm) {
                        s_logger.info("Check if we have disk consolidation after snapshot operation");
                        boolean chainConsolidated = false;
                        for (String vmdkDsFilePath : backupResult.third()) {
                            s_logger.info("Validate disk chain file:" + vmdkDsFilePath);
                            if (vmMo.getDiskDevice(vmdkDsFilePath) == null) {
                                s_logger.info("" + vmdkDsFilePath + " no longer exists, consolidation detected");
                                chainConsolidated = true;
                                break;
                            } else {
                                s_logger.info("" + vmdkDsFilePath + " is found still in chain");
                            }
                        }
                        if (chainConsolidated) {
                            String topVmdkFilePath = null;
                            try {
                                topVmdkFilePath = vmMo.getDiskCurrentTopBackingFileInChain(backupResult.second());
                            } catch (Exception e) {
                                s_logger.error("Unexpected exception", e);
                            }
                            s_logger.info("Disk has been consolidated, top VMDK is now: " + topVmdkFilePath);
                            if (topVmdkFilePath != null) {
                                DatastoreFile file = new DatastoreFile(topVmdkFilePath);
                                SnapshotObjectTO snapshotInfo = (SnapshotObjectTO) answer.getNewData();
                                VolumeObjectTO vol = new VolumeObjectTO();
                                vol.setUuid(srcSnapshot.getVolume().getUuid());
                                vol.setPath(file.getFileBaseName());
                                snapshotInfo.setVolume(vol);
                            } else {
                                s_logger.error("Disk has been consolidated, but top VMDK is not found ?!");
                            }
                        }
                    }
                } else {
                    s_logger.error("Can not find the snapshot we just used ?!");
                }
            }
            try {
                if (workerVm != null) {
                    // detach volume and destroy worker vm
                    workerVm.detachAllDisks();
                    workerVm.destroy();
                }
            } catch (Throwable e) {
                s_logger.warn("Failed to destroy worker VM: " + workerVMName);
            }
        }
        return answer;
    } catch (Throwable e) {
        if (e instanceof RemoteException) {
            hostService.invalidateServiceContext(context);
        }
        s_logger.error("Unexpecpted exception ", e);
        details = "backup snapshot exception: " + VmwareHelper.getExceptionMessage(e);
        return new CopyCmdAnswer(details);
    }
}
Also used : SnapshotObjectTO(org.apache.cloudstack.storage.to.SnapshotObjectTO) PrimaryDataStoreTO(org.apache.cloudstack.storage.to.PrimaryDataStoreTO) DataStoreTO(com.cloud.agent.api.to.DataStoreTO) VirtualMachineMO(com.cloud.hypervisor.vmware.mo.VirtualMachineMO) VmwareHypervisorHost(com.cloud.hypervisor.vmware.mo.VmwareHypervisorHost) NfsTO(com.cloud.agent.api.to.NfsTO) DatastoreMO(com.cloud.hypervisor.vmware.mo.DatastoreMO) RemoteException(java.rmi.RemoteException) UnsupportedEncodingException(java.io.UnsupportedEncodingException) CloudRuntimeException(com.cloud.utils.exception.CloudRuntimeException) VmwareContext(com.cloud.hypervisor.vmware.util.VmwareContext) DatastoreFile(com.cloud.hypervisor.vmware.mo.DatastoreFile) VolumeObjectTO(org.apache.cloudstack.storage.to.VolumeObjectTO) RemoteException(java.rmi.RemoteException) DatastoreFile(com.cloud.hypervisor.vmware.mo.DatastoreFile) File(java.io.File) CopyCmdAnswer(org.apache.cloudstack.storage.command.CopyCmdAnswer) ManagedObjectReference(com.vmware.vim25.ManagedObjectReference)

Aggregations

SnapshotObjectTO (org.apache.cloudstack.storage.to.SnapshotObjectTO)44 CopyCmdAnswer (org.apache.cloudstack.storage.command.CopyCmdAnswer)33 CloudRuntimeException (com.cloud.utils.exception.CloudRuntimeException)23 DataTO (com.cloud.agent.api.to.DataTO)22 NfsTO (com.cloud.agent.api.to.NfsTO)21 DataStoreTO (com.cloud.agent.api.to.DataStoreTO)20 PrimaryDataStoreTO (org.apache.cloudstack.storage.to.PrimaryDataStoreTO)19 VolumeObjectTO (org.apache.cloudstack.storage.to.VolumeObjectTO)16 InternalErrorException (com.cloud.exception.InternalErrorException)14 CreateObjectAnswer (org.apache.cloudstack.storage.command.CreateObjectAnswer)14 Answer (com.cloud.agent.api.Answer)12 TemplateObjectTO (org.apache.cloudstack.storage.to.TemplateObjectTO)11 Connection (com.xensource.xenapi.Connection)9 XenAPIException (com.xensource.xenapi.Types.XenAPIException)9 VDI (com.xensource.xenapi.VDI)9 XmlRpcException (org.apache.xmlrpc.XmlRpcException)9 SR (com.xensource.xenapi.SR)8 URI (java.net.URI)7 ConfigurationException (javax.naming.ConfigurationException)7 S3TO (com.cloud.agent.api.to.S3TO)6