mirror of https://github.com/apache/cloudstack.git
CLOUDSTACK-2630: fix delta snashpt
This commit is contained in:
parent
fa358cf01f
commit
d22bea6031
|
|
@ -334,18 +334,25 @@ public class SnapshotServiceImpl implements SnapshotService {
|
|||
|
||||
protected Void deleteSnapshotCallback(AsyncCallbackDispatcher<SnapshotServiceImpl, CommandResult> callback,
|
||||
DeleteSnapshotContext<CommandResult> context) {
|
||||
|
||||
CommandResult result = callback.getResult();
|
||||
AsyncCallFuture<SnapshotResult> future = context.future;
|
||||
SnapshotInfo snapshot = context.snapshot;
|
||||
if (result.isFailed()) {
|
||||
s_logger.debug("delete snapshot failed" + result.getResult());
|
||||
snapshot.processEvent(ObjectInDataStoreStateMachine.Event.OperationFailed);
|
||||
SnapshotResult res = new SnapshotResult(context.snapshot, null);
|
||||
future.complete(res);
|
||||
return null;
|
||||
SnapshotResult res = null;
|
||||
try {
|
||||
if (result.isFailed()) {
|
||||
s_logger.debug("delete snapshot failed" + result.getResult());
|
||||
snapshot.processEvent(ObjectInDataStoreStateMachine.Event.OperationFailed);
|
||||
res = new SnapshotResult(context.snapshot, null);
|
||||
res.setResult(result.getResult());
|
||||
} else {
|
||||
snapshot.processEvent(ObjectInDataStoreStateMachine.Event.OperationSuccessed);
|
||||
res = new SnapshotResult(context.snapshot, null);
|
||||
}
|
||||
} catch (Exception e) {
|
||||
s_logger.debug("Failed to in deleteSnapshotCallback", e);
|
||||
res.setResult(e.toString());
|
||||
}
|
||||
snapshot.processEvent(ObjectInDataStoreStateMachine.Event.OperationSuccessed);
|
||||
SnapshotResult res = new SnapshotResult(context.snapshot, null);
|
||||
future.complete(res);
|
||||
return null;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -42,6 +42,7 @@ public class SnapshotStateMachineManagerImpl implements SnapshotStateMachineMana
|
|||
stateMachine.addTransition(Snapshot.State.Creating, Event.OperationNotPerformed, Snapshot.State.BackedUp);
|
||||
stateMachine.addTransition(Snapshot.State.Creating, Event.OperationFailed, Snapshot.State.Error);
|
||||
stateMachine.addTransition(Snapshot.State.CreatedOnPrimary, Event.BackupToSecondary, Snapshot.State.BackingUp);
|
||||
stateMachine.addTransition(State.CreatedOnPrimary, Event.OperationNotPerformed, State.BackedUp);
|
||||
stateMachine.addTransition(Snapshot.State.BackingUp, Event.OperationSucceeded, Snapshot.State.BackedUp);
|
||||
stateMachine.addTransition(Snapshot.State.BackingUp, Event.OperationFailed, Snapshot.State.CreatedOnPrimary);
|
||||
stateMachine.addTransition(Snapshot.State.BackedUp, Event.DestroyRequested, Snapshot.State.Destroying);
|
||||
|
|
@ -49,7 +50,7 @@ public class SnapshotStateMachineManagerImpl implements SnapshotStateMachineMana
|
|||
stateMachine.addTransition(Snapshot.State.Copying, Event.OperationSucceeded, Snapshot.State.BackedUp);
|
||||
stateMachine.addTransition(Snapshot.State.Copying, Event.OperationFailed, Snapshot.State.BackedUp);
|
||||
stateMachine.addTransition(Snapshot.State.Destroying, Event.OperationSucceeded, Snapshot.State.Destroyed);
|
||||
stateMachine.addTransition(Snapshot.State.Destroying, Event.OperationFailed, Snapshot.State.Error);
|
||||
stateMachine.addTransition(Snapshot.State.Destroying, Event.OperationFailed, State.BackedUp);
|
||||
|
||||
stateMachine.registerListener(new SnapshotStateListener());
|
||||
}
|
||||
|
|
|
|||
|
|
@ -127,21 +127,23 @@ public class XenserverSnapshotStrategy extends SnapshotStrategyBase {
|
|||
return this.snapshotSvr.backupSnapshot(snapshot);
|
||||
}
|
||||
|
||||
protected void deleteSnapshotChain(SnapshotInfo snapshot) {
|
||||
while (snapshot != null) {
|
||||
protected boolean deleteSnapshotChain(SnapshotInfo snapshot) {
|
||||
s_logger.debug("delete snapshot chain for snapshot: " + snapshot.getId());
|
||||
boolean result = false;
|
||||
while (snapshot != null && (snapshot.getState() == Snapshot.State.Destroying || snapshot.getState()
|
||||
== Snapshot.State.Destroyed || snapshot.getState() == Snapshot.State.Error)) {
|
||||
SnapshotInfo child = snapshot.getChild();
|
||||
SnapshotInfo parent = snapshot.getParent();
|
||||
if (child == null) {
|
||||
if (parent == null || !parent.getPath().equalsIgnoreCase(snapshot.getPath())) {
|
||||
this.snapshotSvr.deleteSnapshot(snapshot);
|
||||
snapshot = parent;
|
||||
continue;
|
||||
}
|
||||
break;
|
||||
} else {
|
||||
|
||||
if (child != null) {
|
||||
s_logger.debug("the snapshot has child, can't delete it on the storage");
|
||||
break;
|
||||
}
|
||||
s_logger.debug("Snapshot: " + snapshot.getId() + " doesn't have children, so it's ok to delete it and its parents");
|
||||
SnapshotInfo parent = snapshot.getParent();
|
||||
result = this.snapshotSvr.deleteSnapshot(snapshot);
|
||||
snapshot = parent;
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
@ -151,36 +153,47 @@ public class XenserverSnapshotStrategy extends SnapshotStrategyBase {
|
|||
return true;
|
||||
}
|
||||
|
||||
|
||||
if (snapshotVO.getState() == Snapshot.State.CreatedOnPrimary) {
|
||||
s_logger.debug("delete snapshot on primary storage:");
|
||||
snapshotVO.setState(Snapshot.State.Destroyed);
|
||||
snapshotDao.update(snapshotId, snapshotVO);
|
||||
return true;
|
||||
}
|
||||
|
||||
if (!Snapshot.State.BackedUp.equals(snapshotVO.getState())) {
|
||||
throw new InvalidParameterValueException("Can't delete snapshotshot " + snapshotId
|
||||
+ " due to it is not in BackedUp Status");
|
||||
}
|
||||
|
||||
if (s_logger.isDebugEnabled()) {
|
||||
s_logger.debug("Calling deleteSnapshot for snapshotId: " + snapshotId);
|
||||
}
|
||||
|
||||
// firt mark the snapshot as destroyed, so that ui can't see it, but we
|
||||
// may not destroy the snapshot on the storage, as other snaphosts may
|
||||
// depend on it.
|
||||
SnapshotInfo snapshotOnPrimary = this.snapshotDataFactory.getSnapshot(snapshotId, DataStoreRole.Primary);
|
||||
SnapshotObject obj = (SnapshotObject) snapshotOnPrimary;
|
||||
SnapshotInfo snapshotOnImage = this.snapshotDataFactory.getSnapshot(snapshotId, DataStoreRole.Image);
|
||||
if (snapshotOnImage == null) {
|
||||
s_logger.debug("Can't find snapshot on backup storage, delete it in db");
|
||||
snapshotDao.remove(snapshotId);
|
||||
}
|
||||
|
||||
SnapshotObject obj = (SnapshotObject) snapshotOnImage;
|
||||
try {
|
||||
obj.processEvent(Snapshot.Event.DestroyRequested);
|
||||
} catch (NoTransitionException e) {
|
||||
s_logger.debug("Failed to destroy snapshot: " + e.toString());
|
||||
s_logger.debug("Failed to set the state to destroying: ", e);
|
||||
return false;
|
||||
}
|
||||
|
||||
try {
|
||||
SnapshotInfo snapshotOnImage = this.snapshotDataFactory.getSnapshot(snapshotId, DataStoreRole.Image);
|
||||
if (snapshotOnImage != null) {
|
||||
deleteSnapshotChain(snapshotOnImage);
|
||||
}
|
||||
|
||||
boolean result = deleteSnapshotChain(snapshotOnImage);
|
||||
obj.processEvent(Snapshot.Event.OperationSucceeded);
|
||||
if (result) {
|
||||
//snapshot is deleted on backup storage, need to delete it on primary storage
|
||||
SnapshotDataStoreVO snapshotOnPrimary = snapshotStoreDao.findBySnapshot(snapshotId, DataStoreRole.Primary);
|
||||
snapshotOnPrimary.setState(State.Destroyed);
|
||||
snapshotStoreDao.update(snapshotOnPrimary.getId(), snapshotOnPrimary);
|
||||
}
|
||||
} catch (Exception e) {
|
||||
s_logger.debug("Failed to delete snapshot: " + e.toString());
|
||||
s_logger.debug("Failed to delete snapshot: ", e);
|
||||
try {
|
||||
obj.processEvent(Snapshot.Event.OperationFailed);
|
||||
} catch (NoTransitionException e1) {
|
||||
|
|
|
|||
|
|
@ -219,10 +219,9 @@ public abstract class BaseImageStoreDriverImpl implements ImageStoreDriver {
|
|||
|
||||
@Override
|
||||
public void deleteAsync(DataStore dataStore, DataObject data, AsyncCompletionCallback<CommandResult> callback) {
|
||||
DeleteCommand cmd = new DeleteCommand(data.getTO());
|
||||
|
||||
CommandResult result = new CommandResult();
|
||||
try {
|
||||
DeleteCommand cmd = new DeleteCommand(data.getTO());
|
||||
EndPoint ep = _epSelector.select(data);
|
||||
Answer answer = ep.sendMessage(cmd);
|
||||
if (answer != null && !answer.getResult()) {
|
||||
|
|
|
|||
|
|
@ -1160,7 +1160,7 @@ public class XenServerStorageProcessor implements StorageProcessor {
|
|||
String backupUuid = UUID.randomUUID().toString();
|
||||
String results = hypervisorResource.callHostPluginAsync(conn, "vmopsSnapshot", "backupSnapshot", wait,
|
||||
"primaryStorageSRUuid", primaryStorageSRUuid, "path", path, "secondaryStorageMountPath", secondaryStorageMountPath,
|
||||
"snapshotUuid", snapshotUuid, "prevBackupUuid", prevBackupUuid, "backupUuid", backupUuid, "isISCSI", isISCSI.toString(), "localMountPath", localMountPoint);
|
||||
"snapshotUuid", snapshotUuid, "prevBackupUuid", prevBackupUuid, "backupUuid", backupUuid, "isISCSI", isISCSI.toString(), "localMountPoint", localMountPoint);
|
||||
String errMsg = null;
|
||||
if (results == null || results.isEmpty()) {
|
||||
errMsg = "Could not copy backupUuid: " + backupSnapshotUuid
|
||||
|
|
|
|||
|
|
@ -504,7 +504,7 @@ def backupSnapshot(session, args):
|
|||
# on it.
|
||||
backupsDir = mountSnapshotsDir(secondaryStorageMountPath, localMountPoint, path)
|
||||
util.SMlog("Backups dir " + backupsDir)
|
||||
|
||||
prevBackupUuid = prevBackupUuid.split("/")[-1]
|
||||
# Check existence of snapshot on primary storage
|
||||
isfile(baseCopyPath, isISCSI)
|
||||
if prevBackupUuid:
|
||||
|
|
|
|||
|
|
@ -1429,25 +1429,10 @@ public class NfsSecondaryStorageResource extends ServerResourceBase implements S
|
|||
return new Answer(cmd, false, errorMessage);
|
||||
}
|
||||
} else if (dstore instanceof SwiftTO) {
|
||||
SwiftTO swiftTO = (SwiftTO)dstore;
|
||||
String path = obj.getPath();
|
||||
String filename = StringUtils.substringAfterLast(path, "/"); // assuming
|
||||
// that
|
||||
// the
|
||||
// filename
|
||||
// is
|
||||
// the
|
||||
// last
|
||||
// section
|
||||
// in
|
||||
// the
|
||||
// path
|
||||
String volumeId = StringUtils.substringAfterLast(StringUtils.substringBeforeLast(path, "/"), "/");
|
||||
String result = swiftDelete((SwiftTO) dstore, "V-" + volumeId, filename);
|
||||
if (result != null) {
|
||||
String errMsg = "failed to delete snapshot " + filename + " , err=" + result;
|
||||
s_logger.warn(errMsg);
|
||||
return new Answer(cmd, false, errMsg);
|
||||
}
|
||||
SwiftUtil.deleteObject(swiftTO, path);
|
||||
|
||||
return new Answer(cmd, true, "Deleted snapshot " + path + " from swift");
|
||||
} else {
|
||||
return new Answer(cmd, false, "Unsupported image data store: " + dstore);
|
||||
|
|
|
|||
|
|
@ -203,4 +203,39 @@ public class SwiftUtil {
|
|||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
public static String[] splitSwiftPath(String path) {
|
||||
int index = path.indexOf(File.separator);
|
||||
if (index == -1) {
|
||||
return null;
|
||||
}
|
||||
String[] paths = new String[2];
|
||||
paths[0] = path.substring(0, index);
|
||||
paths[1] = path.substring(index + 1);
|
||||
return paths;
|
||||
}
|
||||
|
||||
public static boolean deleteObject(SwiftClientCfg cfg, String path) {
|
||||
Script command = new Script("/bin/bash", logger);
|
||||
command.add("-c");
|
||||
|
||||
String[] paths = splitSwiftPath(path);
|
||||
if (paths == null) {
|
||||
return false;
|
||||
}
|
||||
String container = paths[0];
|
||||
String objectName = paths[1];
|
||||
|
||||
StringBuilder swiftCmdBuilder = buildSwiftCmd(cfg);
|
||||
swiftCmdBuilder.append(" delete ");
|
||||
swiftCmdBuilder.append(container);
|
||||
swiftCmdBuilder.append(" ");
|
||||
swiftCmdBuilder.append(objectName);
|
||||
|
||||
|
||||
command.add(swiftCmdBuilder.toString());
|
||||
OutputInterpreter.AllLinesParser parser = new OutputInterpreter.AllLinesParser();
|
||||
String result = command.execute(parser);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in New Issue