Updated Branches: refs/heads/4.2-workplace 81a40bef3 -> 743c7b7cd
use vdi.copy to extract delta. Project: http://git-wip-us.apache.org/repos/asf/cloudstack/repo Commit: http://git-wip-us.apache.org/repos/asf/cloudstack/commit/743c7b7c Tree: http://git-wip-us.apache.org/repos/asf/cloudstack/tree/743c7b7c Diff: http://git-wip-us.apache.org/repos/asf/cloudstack/diff/743c7b7c Branch: refs/heads/4.2-workplace Commit: 743c7b7cddb6e9c8c35ae3c8cf0814bc993870d0 Parents: 81a40be Author: Anthony Xu <[email protected]> Authored: Fri Nov 15 18:23:22 2013 -0800 Committer: Anthony Xu <[email protected]> Committed: Fri Nov 15 18:23:22 2013 -0800 ---------------------------------------------------------------------- .../xen/resource/CitrixResourceBase.java | 108 ++++++++++++++++++- .../hypervisor/xenserver/cloud-plugin-snapshot | 42 +++++++- 2 files changed, 143 insertions(+), 7 deletions(-) ---------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/cloudstack/blob/743c7b7c/plugins/hypervisors/xen/src/com/cloud/hypervisor/xen/resource/CitrixResourceBase.java ---------------------------------------------------------------------- diff --git a/plugins/hypervisors/xen/src/com/cloud/hypervisor/xen/resource/CitrixResourceBase.java b/plugins/hypervisors/xen/src/com/cloud/hypervisor/xen/resource/CitrixResourceBase.java index 4680e93..0f863cd 100644 --- a/plugins/hypervisors/xen/src/com/cloud/hypervisor/xen/resource/CitrixResourceBase.java +++ b/plugins/hypervisors/xen/src/com/cloud/hypervisor/xen/resource/CitrixResourceBase.java @@ -3881,9 +3881,108 @@ public abstract class CitrixResourceBase implements ServerResource, HypervisorRe return lfilename; } + protected SR createFileSR(Connection conn, String path, String location) { + try { + Map<String, String> deviceConfig = new HashMap<String, String>(); + deviceConfig.put("path", path); + Host host = Host.getByUuid(conn, _host.uuid); + SR sr = SR.create(conn, host, deviceConfig, new Long(0), path, "file", "file", "file", false, + new HashMap<String, String>()); + sr.setNameLabel(conn, path + "-File"); + sr.setNameDescription(conn, location); + + sr.scan(conn); + return sr; + } catch (Exception e) { + String msg = "createFileSR failed! due to " + e.toString(); + s_logger.warn(msg, e); + throw new CloudRuntimeException(msg, e); + } + } + + protected String backupSnapshot2(Connection conn, String primaryStorageSRUuid, Long dcId, Long accountId, + Long volumeId, String secondaryStorageMountPath, String snapshotUuid, String snashotPaPaUuid, + String prevBackupUuid, Boolean isISCSI, int wait, Long secHostId) { + String errMsg = null; + boolean mounted = false; + boolean filesrcreated = false; + boolean copied = false; + if (prevBackupUuid == null) { + prevBackupUuid = ""; + } + SR ssSR = null; + String localDir = "/var/cloud_mount/" + UUID.randomUUID().toString(); + String remoteDir = secondaryStorageMountPath + "/snapshots/" + accountId + "/" + volumeId + "/"; + + try { + String results = callHostPluginAsync(conn, "cloud-plugin-snapshot", "mountNfsSecondaryStorage", wait, + "localDir", localDir, "remoteDir", remoteDir); + if (results == null || results.isEmpty()) { + errMsg = "Could not mount secondary storage " + remoteDir + " on host " + _host.ip; + s_logger.warn(errMsg); + throw new CloudRuntimeException(errMsg); + } + mounted = true; + + ssSR = createFileSR(conn, localDir, remoteDir); + filesrcreated = true; + + VDI snapshotvdi = VDI.getByUuid(conn, snapshotUuid); + Task task = null; + if (wait == 0) { + wait = 2 * 60 * 60; + } + VDI dvdi = null; + try { + task = snapshotvdi.copyAsync(conn, ssSR); + // uncomment below to enable delta snapshot + // task = snapshotvdi.copyAsync(ssr, { "base-src": + // snashotPaPaUuid, "base-dst": prevBackupUuid }) + // poll every 1 seconds , + waitForTask(conn, task, 1000, wait * 1000); + checkForSuccess(conn, task); + dvdi = Types.toVDI(task, conn); + copied = true; + } catch (TimeoutException e) { + throw new CloudRuntimeException(e.toString()); + } finally { + if (task != null) { + try { + task.destroy(conn); + } catch (Exception e1) { + s_logger.warn("unable to destroy task(" + task.toString() + ") on host(" + _host.uuid + + ") due to ", e1); + } + } + } + String backupUuid = dvdi.getUuid(conn); + return backupUuid; + } catch (Exception e) { + String msg = "Exception in backupsnapshot stage due to " + e.toString(); + s_logger.debug(msg); + throw new CloudRuntimeException(msg, e); + } finally { + try { + if (filesrcreated && ssSR != null) { + ssSR.forget(conn); + } + if (mounted) { + String results = callHostPluginAsync(conn, "cloud-plugin-snapshot", "umountNfsSecondaryStorage", + wait, "localDir", localDir); + if (results == null || results.isEmpty()) { + errMsg = "Could not umount secondary storage " + remoteDir + " on host " + _host.ip; + s_logger.debug(errMsg); + } + } + } catch (Exception e) { + s_logger.debug("Exception in backupsnapshot cleanup stage due to " + e.toString()); + } + } + } + protected String backupSnapshot(Connection conn, String primaryStorageSRUuid, Long dcId, Long accountId, - Long volumeId, String secondaryStorageMountPath, String snapshotUuid, String prevBackupUuid, Boolean isISCSI, int wait, Long secHostId) { + Long volumeId, String secondaryStorageMountPath, String snapshotUuid, String snashotPaPaUuid, String prevBackupUuid, Boolean isISCSI, int wait, Long secHostId) { String backupSnapshotUuid = null; if (prevBackupUuid == null) { @@ -7387,13 +7486,14 @@ public abstract class CitrixResourceBase implements ServerResource, HypervisorRe String secondaryStorageMountPath = uri.getHost() + ":" + uri.getPath(); VDI snapshotVdi = getVDIbyUuid(conn, snapshotUuid); String snapshotPaUuid = null; + String snashotPaPaUuid = null; if ( prevBackupUuid != null ) { try { snapshotPaUuid = getVhdParent(conn, psUuid, snapshotUuid, isISCSI); if( snapshotPaUuid != null ) { - String snashotPaPaPaUuid = getVhdParent(conn, psUuid, snapshotPaUuid, isISCSI); + snashotPaPaUuid = getVhdParent(conn, psUuid, snapshotPaUuid, isISCSI); String prevSnashotPaUuid = getVhdParent(conn, psUuid, prevSnapshotUuid, isISCSI); - if (snashotPaPaPaUuid != null && prevSnashotPaUuid!= null && prevSnashotPaUuid.equals(snashotPaPaPaUuid)) { + if (snashotPaPaUuid != null && prevSnashotPaUuid!= null && prevSnashotPaUuid.equals(snashotPaPaUuid)) { fullbackup = false; } } @@ -7449,7 +7549,7 @@ public abstract class CitrixResourceBase implements ServerResource, HypervisorRe } else if (cmd.getS3() != null) { backupSnapshotToS3(conn, cmd.getS3(), primaryStorageSRUuid, snapshotPaUuid, isISCSI, wait); } else { - snapshotBackupUuid = backupSnapshot(conn, primaryStorageSRUuid, dcId, accountId, volumeId, secondaryStorageMountPath, snapshotUuid, prevBackupUuid, isISCSI, wait, secHostId); + snapshotBackupUuid = backupSnapshot(conn, primaryStorageSRUuid, dcId, accountId, volumeId, secondaryStorageMountPath, snapshotUuid, snashotPaPaUuid, prevBackupUuid, isISCSI, wait, secHostId); success = (snapshotBackupUuid != null); } } http://git-wip-us.apache.org/repos/asf/cloudstack/blob/743c7b7c/scripts/vm/hypervisor/xenserver/cloud-plugin-snapshot ---------------------------------------------------------------------- diff --git a/scripts/vm/hypervisor/xenserver/cloud-plugin-snapshot b/scripts/vm/hypervisor/xenserver/cloud-plugin-snapshot index ae2f9aa..8da1485 100644 --- a/scripts/vm/hypervisor/xenserver/cloud-plugin-snapshot +++ b/scripts/vm/hypervisor/xenserver/cloud-plugin-snapshot @@ -1,4 +1,4 @@ -#!/usr/bin/python + #!/usr/bin/python # Licensed to the Apache Software Foundation (ASF) under one # or more contributor license agreements. See the NOTICE file # distributed with this work for additional information @@ -349,7 +349,7 @@ def mountSnapshotsDir(secondaryStorageMountPath, localMountPointPath, path): mount(snapshotsDir, localMountPointPath) # Create accountId/instanceId dir on localMountPointPath, if it doesn't exist - backupsDir = os.path.join(localMountPointPath, restDir) + backupsDi = os.path.join(localMountPointPath, restDir) makedirs(backupsDir) return backupsDir @@ -376,6 +376,42 @@ def unmountSnapshotsDir(session, args): return "1" +@echo +def mountNfsSecondaryStorage(session, args): + remoteDir = args['remoteDir'] + localDir = args]'localDir'] + makedirs(localDir) + options = "soft,tcp,timeo=133,retrans=1" + try: + cmd = ['mount', '-o', options, remoteDir, localDir] + txt = util.pread2(cmd) + except: + txt = '' + errMsg = "Unexpected error while trying to mount " + remoteDir + " to " + localDir + logging.debug(errMsg) + raise xs_errors.XenError(errMsg) + logging.debug("Successfully mounted " + remoteDir + " to " + localDir) + + return + +@echo +def umountNfsSecondaryStorage(session, args): + localDir = args['localDir'] + try: + cmd = ['umount', localDir] + util.pread2(cmd) + except CommandException: + errMsg = "CommandException raised while trying to umount " + localDir + logging.debug(errMsg) + raise xs_errors.XenError(errMsg) + try: + os.system("rmdir " + localDir) + except: + pass + logging.debug("Successfully unmounted " + localDir) + return + + def getPrimarySRPath(primaryStorageSRUuid, isISCSI): if isISCSI: primarySRDir = lvhdutil.VG_PREFIX + primaryStorageSRUuid @@ -592,6 +628,6 @@ def revert_memory_snapshot(session, args): return "0" if __name__ == "__main__": - XenAPIPlugin.dispatch({"getVhdParent":getVhdParent, "create_secondary_storage_folder":create_secondary_storage_folder, "delete_secondary_storage_folder":delete_secondary_storage_folder, "post_create_private_template":post_create_private_template, "backupSnapshot": backupSnapshot, "deleteSnapshotBackup": deleteSnapshotBackup, "unmountSnapshotsDir": unmountSnapshotsDir, "revert_memory_snapshot":revert_memory_snapshot}) + XenAPIPlugin.dispatch({"getVhdParent":getVhdParent, "create_secondary_storage_folder":create_secondary_storage_folder, "delete_secondary_storage_folder":delete_secondary_storage_folder, "post_create_private_template":post_create_private_template, "backupSnapshot": backupSnapshot, "deleteSnapshotBackup": deleteSnapshotBackup, "unmountSnapshotsDir": unmountSnapshotsDir, "revert_memory_snapshot":revert_memory_snapshot, "mountNfsSecondaryStorage":mountNfsSecondaryStorage, "umountNfsSecondaryStorage":umountNfsSecondaryStorage})
