bug 6882: relink the child to parent after delete snapshot

change dd block size from 512 to 1M, make taking snapstho faster for iscsi primary storage

status 6882: resolved fixed
This commit is contained in:
anthony 2010-11-03 15:59:16 -07:00
parent 6d56d3a939
commit 86d02eaa15
5 changed files with 77 additions and 38 deletions

View File

@ -30,6 +30,7 @@ public class BackupSnapshotCommand extends SnapshotCommand {
private boolean isFirstSnapshotOfRootVolume;
private boolean isVolumeInactive;
private String firstBackupUuid;
private String volumeUUID;
protected BackupSnapshotCommand() {
@ -50,6 +51,7 @@ public class BackupSnapshotCommand extends SnapshotCommand {
Long dcId,
Long accountId,
Long volumeId,
String volumeUUID,
String snapshotUuid,
String prevSnapshotUuid,
String prevBackupUuid,
@ -63,6 +65,7 @@ public class BackupSnapshotCommand extends SnapshotCommand {
this.firstBackupUuid = firstBackupUuid;
this.isFirstSnapshotOfRootVolume = isFirstSnapshotOfRootVolume;
this.isVolumeInactive = isVolumeInactive;
this.volumeUUID = volumeUUID;
}
public String getPrevSnapshotUuid() {
@ -84,5 +87,12 @@ public class BackupSnapshotCommand extends SnapshotCommand {
public boolean isVolumeInactive() {
return isVolumeInactive;
}
/**
* @return the volumeUUID
*/
public String getVolumeUUID() {
return volumeUUID;
}
}

View File

@ -23,6 +23,7 @@ package com.cloud.agent.api;
*/
public class DeleteSnapshotBackupCommand extends SnapshotCommand {
private String childUUID;
private String childChildUUID;
protected DeleteSnapshotBackupCommand() {
@ -59,10 +60,12 @@ public class DeleteSnapshotBackupCommand extends SnapshotCommand {
Long accountId,
Long volumeId,
String backupUUID,
String childUUID)
String childUUID,
String childChildUUID)
{
super(primaryStoragePoolNameLabel, secondaryStoragePoolURL, backupUUID, dcId, accountId, volumeId);
this.childUUID = childUUID;
this.childChildUUID = childChildUUID;
}
/**
@ -72,4 +75,9 @@ public class DeleteSnapshotBackupCommand extends SnapshotCommand {
return childUUID;
}
public String getChildChildUUID() {
return childChildUUID;
}
}

View File

@ -399,30 +399,6 @@ public abstract class CitrixResourceBase implements StoragePoolResource, ServerR
return null;
}
protected boolean currentlyAttached(SR sr, SR.Record rec, PBD pbd, PBD.Record pbdr) {
String status = null;
if (SRType.NFS.equals(rec.type)) {
//status = callHostPlugin("checkMount", "mount", rec.uuid);
return true;
} else if (SRType.LVMOISCSI.equals(rec.type) ) {
String scsiid = pbdr.deviceConfig.get("SCSIid");
if (scsiid.isEmpty()) {
return false;
}
status = callHostPlugin("checkIscsi", "scsiid", scsiid);
} else {
return true;
}
if (status != null && status.equalsIgnoreCase("1")) {
s_logger.debug("currently attached " + pbdr.uuid);
return true;
} else {
s_logger.debug("currently not attached " + pbdr.uuid);
return false;
}
}
protected boolean pingdomr(String host, String port) {
String status;
status = callHostPlugin("pingdomr", "host", host, "port", port);
@ -5383,7 +5359,9 @@ public abstract class CitrixResourceBase implements StoragePoolResource, ServerR
// new one
// and muddle the vhd chain on the secondary storage.
details = "Successfully backedUp the snapshotUuid: " + snapshotUuid + " to secondary storage.";
destroySnapshotOnPrimaryStorage(prevSnapshotUuid);
String volumeUuid = cmd.getVolumeUUID();
destroySnapshotOnPrimaryStorageExceptThis(volumeUuid, snapshotUuid);
}
} catch (XenAPIException e) {
@ -5519,6 +5497,7 @@ public abstract class CitrixResourceBase implements StoragePoolResource, ServerR
String secondaryStoragePoolURL = cmd.getSecondaryStoragePoolURL();
String backupUUID = cmd.getSnapshotUuid();
String childUUID = cmd.getChildUUID();
String childChildUUID = cmd.getChildChildUUID();
String primaryStorageNameLabel = cmd.getPrimaryStoragePoolNameLabel();
String details = null;
@ -5556,7 +5535,7 @@ public abstract class CitrixResourceBase implements StoragePoolResource, ServerR
if (secondaryStorageMountPath == null) {
details = "Couldn't delete snapshot because the URL passed: " + secondaryStoragePoolURL + " is invalid.";
} else {
details = deleteSnapshotBackup(dcId, accountId, volumeId, secondaryStorageMountPath, backupUUID, childUUID, isISCSI);
details = deleteSnapshotBackup(dcId, accountId, volumeId, secondaryStorageMountPath, backupUUID, childUUID, childChildUUID, isISCSI);
success = (details != null && details.equals("1"));
if (success) {
s_logger.debug("Successfully deleted snapshot backup " + backupUUID);
@ -5879,6 +5858,37 @@ public abstract class CitrixResourceBase implements StoragePoolResource, ServerR
return backupSnapshotUuid;
}
private boolean destroySnapshotOnPrimaryStorageExceptThis(String volumeUuid, String avoidSnapshotUuid){
try {
Connection conn = getConnection();
VDI volume = getVDIbyUuid(volumeUuid);
if (volume == null) {
throw new InternalErrorException("Could not destroy snapshot on volume " + volumeUuid + " due to can not find it");
}
Set<VDI> snapshots = volume.getSnapshots(conn);
for( VDI snapshot : snapshots ) {
try {
if(! snapshot.getUuid(conn).equals(avoidSnapshotUuid)) {
snapshot.destroy(conn);
}
} catch (Exception e) {
String msg = "Destroying snapshot: " + snapshot+ " on primary storage failed due to " + e.toString();
s_logger.warn(msg, e);
}
}
s_logger.debug("Successfully destroyed snapshot on volume: " + volumeUuid + " execept this current snapshot "+ avoidSnapshotUuid );
return true;
} catch (XenAPIException e) {
String msg = "Destroying snapshot on volume: " + volumeUuid + " execept this current snapshot "+ avoidSnapshotUuid + " failed due to " + e.toString();
s_logger.error(msg, e);
} catch (Exception e) {
String msg = "Destroying snapshot on volume: " + volumeUuid + " execept this current snapshot "+ avoidSnapshotUuid + " failed due to " + e.toString();
s_logger.warn(msg, e);
}
return false;
}
protected boolean destroySnapshotOnPrimaryStorage(String snapshotUuid) {
// Precondition snapshotUuid != null
@ -5902,10 +5912,10 @@ public abstract class CitrixResourceBase implements StoragePoolResource, ServerR
return false;
}
protected String deleteSnapshotBackup(Long dcId, Long accountId, Long volumeId, String secondaryStorageMountPath, String backupUUID, String childUUID, Boolean isISCSI) {
protected String deleteSnapshotBackup(Long dcId, Long accountId, Long volumeId, String secondaryStorageMountPath, String backupUUID, String childUUID, String childChildUUID, Boolean isISCSI) {
// If anybody modifies the formatting below again, I'll skin them
String result = callHostPlugin("deleteSnapshotBackup", "backupUUID", backupUUID, "childUUID", childUUID, "dcId", dcId.toString(), "accountId", accountId.toString(),
String result = callHostPlugin("deleteSnapshotBackup", "backupUUID", backupUUID, "childUUID", childUUID, "childChildUUID", childChildUUID, "dcId", dcId.toString(), "accountId", accountId.toString(),
"volumeId", volumeId.toString(), "secondaryStorageMountPath", secondaryStorageMountPath, "isISCSI", isISCSI.toString());
return result;

View File

@ -580,7 +580,7 @@ def copyfile(fromFile, toFile, isISCSI):
errMsg = ''
if isISCSI:
try:
cmd = ['dd', 'if=' + fromFile, 'of=' + toFile]
cmd = ['dd', 'if=' + fromFile, 'of=' + toFile , 'bs=1M']
txt = util.pread2(cmd)
except:
txt = ''
@ -685,7 +685,7 @@ def rename(originalVHD, newVHD):
raise xs_errors.XenError(errMsg)
return
def coalesceToChild(backupVHD, childUUID):
def coalesceToChild(backupVHD, childUUID, childChildUUID):
# coalesce childVHD with its parent
childVHD = getVHD(childUUID, False)
util.SMlog("childVHD: " + childVHD)
@ -698,6 +698,9 @@ def coalesceToChild(backupVHD, childUUID):
# rename the existing backupVHD file to childVHD
# childVHD file automatically gets overwritten
rename(backupVHD, childVHD)
if childChildUUID:
childChildVHD = getVHD(childChildUUID, False)
setParent(childVHD, childChildVHD)
# parent of the newly coalesced file still remains the same.
# child of childVHD has it's parent name still set to childVHD.
@ -1110,7 +1113,8 @@ def backupSnapshot(session, args):
# Check existence of snapshot on primary storage
isfile(baseCopyPath, isISCSI)
# copy baseCopyPath to backupsDir
backupVHD = getVHD(baseCopyUuid, False)
backupUuid = util.gen_uuid()
backupVHD = getVHD(backupUuid, False)
backupFile = os.path.join(backupsDir, backupVHD)
copyfile(baseCopyPath, backupFile, isISCSI)
@ -1136,7 +1140,7 @@ def backupSnapshot(session, args):
prevBackupVHD = getVHD(prevBackupUuid, False)
setParent(prevBackupVHD, backupFile)
txt = "1#" + baseCopyUuid
txt = "1#" + backupUuid
return txt
def createDummyVHD(baseCopyPath, backupsDir):
@ -1166,6 +1170,7 @@ def deleteSnapshotBackup(session, args):
secondaryStorageMountPath = args['secondaryStorageMountPath']
backupUUID = args['backupUUID']
childUUID = args['childUUID']
childChildUUID = args['childChildUUID']
backupsDir = mountSnapshotsDir(secondaryStorageMountPath, "snapshots", dcId, accountId, volumeId)
# chdir to the backupsDir for convenience
@ -1182,7 +1187,7 @@ def deleteSnapshotBackup(session, args):
# Case 1) childUUID exists
if childUUID:
coalesceToChild(backupVHD, childUUID)
coalesceToChild(backupVHD, childUUID, childChildUUID)
else:
# Just delete the backupVHD
try:

View File

@ -592,6 +592,7 @@ public class SnapshotManagerImpl implements SnapshotManager {
dcId,
accountId,
volumeId,
volume.getPath(),
snapshotUuid,
prevSnapshotUuid,
prevBackupUuid,
@ -937,8 +938,11 @@ public class SnapshotManagerImpl implements SnapshotManager {
String backupOfSnapshot = snapshot.getBackupSnapshotId();
String backupOfNextSnapshot = null;
if (nextSnapshot != null) {
backupOfNextSnapshot = nextSnapshot.getBackupSnapshotId();
backupOfNextSnapshot = nextSnapshot.getBackupSnapshotId();
String backupOfNextNextSnapshot = null;
SnapshotVO nextNextSnapshot = _snapshotDao.findNextSnapshot(nextSnapshot.getId());
if( nextNextSnapshot != null ) {
backupOfNextNextSnapshot = nextNextSnapshot.getBackupSnapshotId();
}
DeleteSnapshotBackupCommand cmd =
@ -948,7 +952,8 @@ public class SnapshotManagerImpl implements SnapshotManager {
accountId,
volumeId,
backupOfSnapshot,
backupOfNextSnapshot);
backupOfNextSnapshot,
backupOfNextNextSnapshot);
details = "Failed to destroy snapshot id:" + snapshotId + " for volume: " + volume.getId();
Answer answer = _storageMgr.sendToHostsOnStoragePool(volume.getPoolId(),
@ -1294,7 +1299,8 @@ public class SnapshotManagerImpl implements SnapshotManager {
accountId,
volumeId,
backupOfSnapshot,
backupOfNextSnapshot);
backupOfNextSnapshot,
null);
String basicErrMsg = "Failed to destroy snapshot id: " + snapshotId + " for volume id: " + volumeId;
Answer answer = _storageMgr.sendToHostsOnStoragePool(volume.getPoolId(), cmd, basicErrMsg, _totalRetries, _pauseInterval, _shouldBeSnapshotCapable);