Swift: DeleteSnapshotBackupCommand and DeleteSnapshotsDirCommand are executed in SSVM

This commit is contained in:
anthony 2011-10-21 19:53:48 -07:00
parent 19df7ed8af
commit 0df249172d
14 changed files with 194 additions and 388 deletions

View File

@ -19,10 +19,7 @@
package com.cloud.agent.resource.computing;
import java.io.BufferedInputStream;
import java.io.BufferedReader;
import java.io.DataInputStream;
import java.io.EOFException;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
@ -85,9 +82,6 @@ import com.cloud.agent.api.CreatePrivateTemplateFromVolumeCommand;
import com.cloud.agent.api.CreateStoragePoolCommand;
import com.cloud.agent.api.CreateVolumeFromSnapshotAnswer;
import com.cloud.agent.api.CreateVolumeFromSnapshotCommand;
import com.cloud.agent.api.DeleteSnapshotBackupAnswer;
import com.cloud.agent.api.DeleteSnapshotBackupCommand;
import com.cloud.agent.api.DeleteSnapshotsDirCommand;
import com.cloud.agent.api.DeleteStoragePoolCommand;
import com.cloud.agent.api.FenceAnswer;
import com.cloud.agent.api.FenceCommand;
@ -891,10 +885,6 @@ public class LibvirtComputingResource extends ServerResourceBase implements Serv
return execute((ManageSnapshotCommand) cmd);
} else if (cmd instanceof BackupSnapshotCommand) {
return execute((BackupSnapshotCommand) cmd);
} else if (cmd instanceof DeleteSnapshotBackupCommand) {
return execute((DeleteSnapshotBackupCommand) cmd);
} else if (cmd instanceof DeleteSnapshotsDirCommand) {
return execute((DeleteSnapshotsDirCommand) cmd);
} else if (cmd instanceof CreateVolumeFromSnapshotCommand) {
return execute((CreateVolumeFromSnapshotCommand) cmd);
} else if (cmd instanceof CreatePrivateTemplateFromSnapshotCommand) {
@ -1293,52 +1283,6 @@ public class LibvirtComputingResource extends ServerResourceBase implements Serv
return new BackupSnapshotAnswer(cmd, true, null, snapshotDestPath + File.separator + snapshotName, true);
}
protected DeleteSnapshotBackupAnswer execute(final DeleteSnapshotBackupCommand cmd) {
Long dcId = cmd.getDataCenterId();
Long accountId = cmd.getAccountId();
Long volumeId = cmd.getVolumeId();
try {
Connect conn = LibvirtConnection.getConnection();
StoragePool secondaryStoragePool = _storageResource.getStoragePoolbyURI(conn, new URI(cmd.getSecondaryStoragePoolURL()));
LibvirtStoragePoolDef spd = _storageResource.getStoragePoolDef(conn, secondaryStoragePool);
String ssPmountPath = spd.getTargetPath();
String snapshotDestPath = ssPmountPath + File.separator + "snapshots" + File.separator + dcId + File.separator + accountId + File.separator + volumeId;
final Script command = new Script(_manageSnapshotPath, _cmdsTimeout, s_logger);
command.add("-d", snapshotDestPath);
command.add("-n", cmd.getSnapshotName());
command.execute();
} catch (LibvirtException e) {
return new DeleteSnapshotBackupAnswer(cmd, false, e.toString());
} catch (URISyntaxException e) {
return new DeleteSnapshotBackupAnswer(cmd, false, e.toString());
}
return new DeleteSnapshotBackupAnswer(cmd, true, null);
}
protected Answer execute(DeleteSnapshotsDirCommand cmd) {
Long dcId = cmd.getDataCenterId();
Long accountId = cmd.getAccountId();
Long volumeId = cmd.getVolumeId();
try {
Connect conn = LibvirtConnection.getConnection();
StoragePool secondaryStoragePool = _storageResource.getStoragePoolbyURI(conn, new URI(cmd.getSecondaryStoragePoolURL()));
LibvirtStoragePoolDef spd = _storageResource.getStoragePoolDef(conn, secondaryStoragePool);
String ssPmountPath = spd.getTargetPath();
String snapshotDestPath = ssPmountPath + File.separator + "snapshots" + File.separator + dcId + File.separator + accountId + File.separator + volumeId;
final Script command = new Script(_manageSnapshotPath, _cmdsTimeout, s_logger);
command.add("-d", snapshotDestPath);
command.add("-f");
command.execute();
} catch (LibvirtException e) {
return new Answer(cmd, false, e.toString());
} catch (URISyntaxException e) {
return new Answer(cmd, false, e.toString());
}
return new Answer(cmd, true, null);
}
protected CreateVolumeFromSnapshotAnswer execute(final CreateVolumeFromSnapshotCommand cmd) {
try {

View File

@ -17,14 +17,33 @@
*/
package com.cloud.agent.api;
import com.cloud.agent.api.to.SwiftTO;
/**
* This command encapsulates a primitive operation which enables coalescing the backed up VHD snapshots on the secondary server
* This currently assumes that the secondary storage are mounted on the XenServer.
*/
public class DeleteSnapshotBackupCommand extends SnapshotCommand {
private SwiftTO swift;
private Boolean all;
public SwiftTO getSwift() {
return swift;
}
public Boolean isAll() {
return all;
}
public void setAll(Boolean all) {
this.all = all;
}
public void setSwift(SwiftTO swift) {
this.swift = swift;
}
protected DeleteSnapshotBackupCommand() {
}
/**
@ -52,14 +71,15 @@ public class DeleteSnapshotBackupCommand extends SnapshotCommand {
* @param backupUUID The VHD which has to be deleted
* @param childUUID The child VHD file of the backup whose parent is reset to its grandparent.
*/
public DeleteSnapshotBackupCommand(String primaryStoragePoolNameLabel,
public DeleteSnapshotBackupCommand(SwiftTO swift,
String secondaryStoragePoolURL,
Long dcId,
Long accountId,
Long volumeId,
String backupUUID,
String backupName)
String backupUUID, Boolean all)
{
super(primaryStoragePoolNameLabel, secondaryStoragePoolURL, backupUUID, backupName, dcId, accountId, volumeId);
super(null, secondaryStoragePoolURL, backupUUID, null, dcId, accountId, volumeId);
setSwift(swift);
setAll(all);
}
}

View File

@ -21,46 +21,44 @@ package com.cloud.agent.api;
* This command encapsulates a primitive operation which enables coalescing the backed up VHD snapshots on the secondary server
* This currently assumes that the secondary storage are mounted on the XenServer.
*/
public class DeleteSnapshotsDirCommand extends SnapshotCommand {
public class DeleteSnapshotsDirCommand extends Command {
String secondaryStoragePoolURL;
Long dcId;
Long accountId;
Long volumeId;
protected DeleteSnapshotsDirCommand() {
}
/**
* Given 2 VHD files on the secondary storage which are linked in a parent chain as follows:
* backupUUID = parent(childUUID)
* It gets another VHD
* previousBackupVHD = parent(backupUUID)
*
* And
* 1) it coalesces backupUuid into its parent.
* 2) It deletes the VHD file corresponding to backupUuid
* 3) It sets the parent VHD of childUUID to that of previousBackupUuid
*
* It takes care of the cases when
* 1) childUUID is null. - Step 3 is not done.
* 2) previousBackupUUID is null
* - Merge childUUID into its parent backupUUID
* - Set the UUID of the resultant VHD to childUUID
* - Essentially we are deleting the oldest VHD file and setting the current oldest VHD to childUUID
*
* @param volumeName The name of the volume whose snapshot was taken (something like i-3-SV-ROOT)
* @param secondaryStoragePoolURL This is what shows up in the UI when you click on Secondary storage.
* In the code, it is present as: In the vmops.host_details table, there is a field mount.parent. This is the value of that field
* If you have better ideas on how to get it, you are welcome.
* @param backupUUID The VHD which has to be deleted
* @param childUUID The child VHD file of the backup whose parent is reset to its grandparent.
*/
public DeleteSnapshotsDirCommand(String primaryStoragePoolNameLabel,
String secondaryStoragePoolURL,
Long dcId,
Long accountId,
Long volumeId,
String volumePath)
public DeleteSnapshotsDirCommand(String secondaryStoragePoolURL,
Long dcId, Long accountId, Long volumeId)
{
super(primaryStoragePoolNameLabel, secondaryStoragePoolURL, null, null, dcId, accountId, volumeId);
this.setVolumePath(volumePath);
this.secondaryStoragePoolURL = secondaryStoragePoolURL;
this.dcId = dcId;
this.accountId = accountId;
this.volumeId = volumeId;
}
@Override
public boolean executeInSequence() {
return true;
}
public String getSecondaryStoragePoolURL() {
return secondaryStoragePoolURL;
}
public Long getDcId() {
return dcId;
}
public Long getAccountId() {
return accountId;
}
public Long getVolumeId() {
return volumeId;
}
}

View File

@ -48,8 +48,6 @@ import com.cloud.agent.api.Command;
import com.cloud.agent.api.CreatePrivateTemplateFromSnapshotCommand;
import com.cloud.agent.api.CreatePrivateTemplateFromVolumeCommand;
import com.cloud.agent.api.CreateVolumeFromSnapshotCommand;
import com.cloud.agent.api.DeleteSnapshotBackupCommand;
import com.cloud.agent.api.DeleteSnapshotsDirCommand;
import com.cloud.agent.api.DeleteStoragePoolCommand;
import com.cloud.agent.api.GetHostStatsAnswer;
import com.cloud.agent.api.GetHostStatsCommand;
@ -209,12 +207,8 @@ public class HypervResource extends ServerResourceBase implements ServerResource
//return execute((ManageSnapshotCommand) cmd);
} else if (cmd instanceof BackupSnapshotCommand) {
//return execute((BackupSnapshotCommand) cmd);
} else if (cmd instanceof DeleteSnapshotBackupCommand) {
//return execute((DeleteSnapshotBackupCommand) cmd);
} else if (cmd instanceof CreateVolumeFromSnapshotCommand) {
//return execute((CreateVolumeFromSnapshotCommand) cmd);
} else if (cmd instanceof DeleteSnapshotsDirCommand) {
//return execute((DeleteSnapshotsDirCommand) cmd);
} else if (cmd instanceof CreatePrivateTemplateFromVolumeCommand) {
//return execute((CreatePrivateTemplateFromVolumeCommand) cmd);
} else if (cmd instanceof CreatePrivateTemplateFromSnapshotCommand) {

View File

@ -4,21 +4,17 @@
package com.cloud.hypervisor.vmware.manager;
import com.cloud.agent.api.Answer;
import com.cloud.agent.api.BackupSnapshotCommand;
import com.cloud.agent.api.CreatePrivateTemplateFromSnapshotCommand;
import com.cloud.agent.api.CreatePrivateTemplateFromVolumeCommand;
import com.cloud.agent.api.CreateVolumeFromSnapshotCommand;
import com.cloud.agent.api.DeleteSnapshotBackupCommand;
import com.cloud.agent.api.DeleteSnapshotsDirCommand;
import com.cloud.agent.api.storage.CopyVolumeCommand;
import com.cloud.agent.api.storage.PrimaryStorageDownloadCommand;
import com.cloud.agent.api.Answer;
import com.cloud.agent.api.BackupSnapshotCommand;
import com.cloud.agent.api.CreatePrivateTemplateFromSnapshotCommand;
import com.cloud.agent.api.CreatePrivateTemplateFromVolumeCommand;
import com.cloud.agent.api.CreateVolumeFromSnapshotCommand;
import com.cloud.agent.api.storage.CopyVolumeCommand;
import com.cloud.agent.api.storage.PrimaryStorageDownloadCommand;
public interface VmwareStorageManager {
Answer execute(VmwareHostService hostService, PrimaryStorageDownloadCommand cmd);
Answer execute(VmwareHostService hostService, BackupSnapshotCommand cmd);
Answer execute(VmwareHostService hostService, DeleteSnapshotsDirCommand cmd);
Answer execute(VmwareHostService hostService, DeleteSnapshotBackupCommand cmd);
Answer execute(VmwareHostService hostService, CreatePrivateTemplateFromVolumeCommand cmd);
Answer execute(VmwareHostService hostService, CreatePrivateTemplateFromSnapshotCommand cmd);
Answer execute(VmwareHostService hostService, CopyVolumeCommand cmd);

View File

@ -21,9 +21,6 @@ import com.cloud.agent.api.CreatePrivateTemplateFromSnapshotCommand;
import com.cloud.agent.api.CreatePrivateTemplateFromVolumeCommand;
import com.cloud.agent.api.CreateVolumeFromSnapshotAnswer;
import com.cloud.agent.api.CreateVolumeFromSnapshotCommand;
import com.cloud.agent.api.DeleteSnapshotBackupAnswer;
import com.cloud.agent.api.DeleteSnapshotBackupCommand;
import com.cloud.agent.api.DeleteSnapshotsDirCommand;
import com.cloud.agent.api.storage.CopyVolumeAnswer;
import com.cloud.agent.api.storage.CopyVolumeCommand;
import com.cloud.agent.api.storage.CreatePrivateTemplateAnswer;
@ -35,8 +32,6 @@ import com.cloud.hypervisor.vmware.mo.DatacenterMO;
import com.cloud.hypervisor.vmware.mo.DatastoreMO;
import com.cloud.hypervisor.vmware.mo.VirtualMachineMO;
import com.cloud.hypervisor.vmware.mo.VmwareHypervisorHost;
import com.vmware.vim25.VirtualDeviceConfigSpec;
import com.vmware.vim25.VirtualLsiLogicController;
import com.cloud.hypervisor.vmware.util.VmwareContext;
import com.cloud.hypervisor.vmware.util.VmwareHelper;
import com.cloud.storage.JavaStorageLayer;
@ -48,13 +43,14 @@ import com.cloud.utils.StringUtils;
import com.cloud.utils.Ternary;
import com.cloud.utils.script.Script;
import com.vmware.vim25.ManagedObjectReference;
import com.vmware.vim25.VirtualDeviceConfigSpec;
import com.vmware.vim25.VirtualDeviceConfigSpecOperation;
import com.vmware.vim25.VirtualDisk;
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 com.vmware.vim25.VirtualDeviceConfigSpec;
import com.vmware.vim25.VirtualDeviceConfigSpecOperation;
public class VmwareStorageManagerImpl implements VmwareStorageManager {
private static final Logger s_logger = Logger.getLogger(VmwareStorageManagerImpl.class);
@ -244,62 +240,7 @@ public class VmwareStorageManagerImpl implements VmwareStorageManager {
return new BackupSnapshotAnswer(cmd, success, details, snapshotBackupUuid, true);
}
@Override
public Answer execute(VmwareHostService hostService, DeleteSnapshotsDirCommand cmd) {
Long accountId = cmd.getAccountId();
Long volumeId = cmd.getVolumeId();
String secondaryStoragePoolURL = cmd.getSecondaryStoragePoolURL();
String details = null;
boolean success = false;
VmwareContext context = hostService.getServiceContext(cmd);
try {
details = deleteSnapshotDirOnSecondaryStorage(accountId, volumeId, secondaryStoragePoolURL);
if (details == null) {
success = true;
}
} catch (Throwable e) {
if (e instanceof RemoteException) {
hostService.invalidateServiceContext(context);
}
s_logger.error("Unexpecpted exception ", e);
details = "DeleteSnapshotDirCommand exception: " + StringUtils.getExceptionStackInfo(e);
return new Answer(cmd, false, details);
}
return new Answer(cmd, success, details);
}
public Answer execute(VmwareHostService hostService, DeleteSnapshotBackupCommand cmd) {
Long accountId = cmd.getAccountId();
Long volumeId = cmd.getVolumeId();
String secStorageUrl = cmd.getSecondaryStoragePoolURL();
String backupUUID = cmd.getSnapshotUuid();
String details = null;
boolean success = false;
VmwareContext context = hostService.getServiceContext(cmd);
try {
details = deleteSnapshotOnSecondaryStorge(accountId, volumeId, secStorageUrl, backupUUID);
if (details == null) {
success = true;
}
} catch (Throwable e) {
if (e instanceof RemoteException) {
hostService.invalidateServiceContext(context);
}
s_logger.error("Unexpecpted exception ", e);
details = "DeleteSnapshotBackupCommand exception: " + StringUtils.getExceptionStackInfo(e);
return new DeleteSnapshotBackupAnswer(cmd, false, details);
}
return new DeleteSnapshotBackupAnswer(cmd, success, details);
}
@Override
public Answer execute(VmwareHostService hostService, CreatePrivateTemplateFromVolumeCommand cmd) {
@ -793,18 +734,6 @@ public class VmwareStorageManagerImpl implements VmwareStorageManager {
return "Failed to delete snapshot backup file, backupUuid: " + backupUuid;
}
private String deleteSnapshotDirOnSecondaryStorage(long accountId, long volumeId, String secStorageUrl) throws Exception {
String secondaryMountPoint = _mountService.getMountPoint(secStorageUrl);
String snapshotMountRoot = secondaryMountPoint + "/" + getSnapshotRelativeDirInSecStorage(accountId, volumeId);
synchronized(snapshotMountRoot.intern()) {
Script command = new Script(false, "rm", _timeout, s_logger);
command.add("-rf");
command.add(snapshotMountRoot);
return command.execute();
}
}
private Pair<String, String> copyVolumeToSecStorage(VmwareHypervisorHost hyperHost, String vmName, long volumeId, String poolId, String volumePath,
String secStorageUrl, String workerVmName) throws Exception {
String volumeFolder = String.valueOf(volumeId) + "/";

View File

@ -50,9 +50,6 @@ import com.cloud.agent.api.CreatePrivateTemplateFromVolumeCommand;
import com.cloud.agent.api.CreateStoragePoolCommand;
import com.cloud.agent.api.CreateVolumeFromSnapshotAnswer;
import com.cloud.agent.api.CreateVolumeFromSnapshotCommand;
import com.cloud.agent.api.DeleteSnapshotBackupAnswer;
import com.cloud.agent.api.DeleteSnapshotBackupCommand;
import com.cloud.agent.api.DeleteSnapshotsDirCommand;
import com.cloud.agent.api.DeleteStoragePoolCommand;
import com.cloud.agent.api.GetDomRVersionAnswer;
import com.cloud.agent.api.GetDomRVersionCmd;
@ -349,12 +346,8 @@ public class VmwareResource implements StoragePoolResource, ServerResource, Vmwa
answer = execute((ManageSnapshotCommand) cmd);
} else if (cmd instanceof BackupSnapshotCommand) {
answer = execute((BackupSnapshotCommand) cmd);
} else if (cmd instanceof DeleteSnapshotBackupCommand) {
answer = execute((DeleteSnapshotBackupCommand) cmd);
} else if (cmd instanceof CreateVolumeFromSnapshotCommand) {
answer = execute((CreateVolumeFromSnapshotCommand) cmd);
} else if (cmd instanceof DeleteSnapshotsDirCommand) {
answer = execute((DeleteSnapshotsDirCommand) cmd);
} else if (cmd instanceof CreatePrivateTemplateFromVolumeCommand) {
answer = execute((CreatePrivateTemplateFromVolumeCommand) cmd);
} else if (cmd instanceof CreatePrivateTemplateFromSnapshotCommand) {
@ -2332,25 +2325,6 @@ public class VmwareResource implements StoragePoolResource, ServerResource, Vmwa
}
}
protected Answer execute(DeleteSnapshotBackupCommand cmd) {
if (s_logger.isInfoEnabled()) {
s_logger.info("Executing resource DeleteSnapshotBackupCommand: " + _gson.toJson(cmd));
}
try {
VmwareManager mgr = getServiceContext().getStockObject(VmwareManager.CONTEXT_STOCK_NAME);
return mgr.getStorageManager().execute(this, cmd);
} catch (Throwable e) {
if (e instanceof RemoteException) {
s_logger.warn("Encounter remote exception to vCenter, invalidate VMware session context");
invalidateServiceContext();
}
String details = "DeleteSnapshotBackupCommand failed due to " + VmwareHelper.getExceptionMessage(e);
s_logger.error(details);
return new DeleteSnapshotBackupAnswer(cmd, false, details);
}
}
protected Answer execute(CreateVolumeFromSnapshotCommand cmd) {
if (s_logger.isInfoEnabled()) {
@ -2378,26 +2352,6 @@ public class VmwareResource implements StoragePoolResource, ServerResource, Vmwa
return new CreateVolumeFromSnapshotAnswer(cmd, success, details, newVolumeName);
}
protected Answer execute(DeleteSnapshotsDirCommand cmd) {
if (s_logger.isInfoEnabled()) {
s_logger.info("Executing resource DeleteSnapshotsDirCommand: " + _gson.toJson(cmd));
}
try {
VmwareManager mgr = getServiceContext().getStockObject(VmwareManager.CONTEXT_STOCK_NAME);
return mgr.getStorageManager().execute(this, cmd);
} catch (Throwable e) {
if (e instanceof RemoteException) {
s_logger.warn("Encounter remote exception to vCenter, invalidate VMware session context");
invalidateServiceContext();
}
String details = "DeleteSnapshotDirCommand failed due to " + VmwareHelper.getExceptionMessage(e);
s_logger.error(details);
return new Answer(cmd, false, details);
}
}
protected Answer execute(CreatePrivateTemplateFromVolumeCommand cmd) {
if (s_logger.isInfoEnabled()) {
s_logger.info("Executing resource CreatePrivateTemplateFromVolumeCommand: " + _gson.toJson(cmd));

View File

@ -79,9 +79,6 @@ import com.cloud.agent.api.CreatePrivateTemplateFromVolumeCommand;
import com.cloud.agent.api.CreateStoragePoolCommand;
import com.cloud.agent.api.CreateVolumeFromSnapshotAnswer;
import com.cloud.agent.api.CreateVolumeFromSnapshotCommand;
import com.cloud.agent.api.DeleteSnapshotBackupAnswer;
import com.cloud.agent.api.DeleteSnapshotBackupCommand;
import com.cloud.agent.api.DeleteSnapshotsDirCommand;
import com.cloud.agent.api.DeleteStoragePoolCommand;
import com.cloud.agent.api.GetDomRVersionAnswer;
import com.cloud.agent.api.GetDomRVersionCmd;
@ -447,12 +444,8 @@ public abstract class CitrixResourceBase implements ServerResource, HypervisorRe
return execute((ManageSnapshotCommand) cmd);
} else if (clazz == BackupSnapshotCommand.class) {
return execute((BackupSnapshotCommand) cmd);
} else if (clazz == DeleteSnapshotBackupCommand.class) {
return execute((DeleteSnapshotBackupCommand) cmd);
} else if (clazz == CreateVolumeFromSnapshotCommand.class) {
return execute((CreateVolumeFromSnapshotCommand) cmd);
} else if (clazz == DeleteSnapshotsDirCommand.class) {
return execute((DeleteSnapshotsDirCommand) cmd);
} else if (clazz == CreatePrivateTemplateFromVolumeCommand.class) {
return execute((CreatePrivateTemplateFromVolumeCommand) cmd);
} else if (clazz == CreatePrivateTemplateFromSnapshotCommand.class) {
@ -6087,91 +6080,6 @@ public abstract class CitrixResourceBase implements ServerResource, HypervisorRe
return new CreateVolumeFromSnapshotAnswer(cmd, result, details, volumeUUID);
}
protected DeleteSnapshotBackupAnswer execute(final DeleteSnapshotBackupCommand cmd) {
Connection conn = getConnection();
Long dcId = cmd.getDataCenterId();
Long accountId = cmd.getAccountId();
Long volumeId = cmd.getVolumeId();
String secondaryStoragePoolURL = cmd.getSecondaryStoragePoolURL();
String backupUUID = cmd.getSnapshotUuid();
String details = null;
boolean success = false;
URI uri = null;
try {
uri = new URI(secondaryStoragePoolURL);
} catch (URISyntaxException e) {
details = "Error finding the secondary storage URL" + e.getMessage();
s_logger.error(details, e);
}
if (uri != null) {
String secondaryStorageMountPath = uri.getHost() + ":" + uri.getPath();
details = deleteSnapshotBackup(conn, dcId, accountId, volumeId, secondaryStorageMountPath, backupUUID);
success = (details != null && details.equals("1"));
if (success) {
s_logger.debug("Successfully deleted snapshot backup " + backupUUID);
}
}
return new DeleteSnapshotBackupAnswer(cmd, true, details);
}
protected Answer execute(DeleteSnapshotsDirCommand cmd) {
Connection conn = getConnection();
Long dcId = cmd.getDataCenterId();
Long accountId = cmd.getAccountId();
Long volumeId = cmd.getVolumeId();
String secondaryStoragePoolURL = cmd.getSecondaryStoragePoolURL();
String snapshotUUID = cmd.getSnapshotUuid();
String primaryStorageNameLabel = cmd.getPrimaryStoragePoolNameLabel();
String details = null;
boolean success = false;
SR primaryStorageSR = null;
try {
primaryStorageSR = getSRByNameLabelandHost(conn, primaryStorageNameLabel);
if (primaryStorageSR == null) {
details = "Primary Storage SR could not be created from the name label: " + primaryStorageNameLabel;
}
} catch (XenAPIException e) {
details = "Couldn't determine primary SR type " + e.getMessage();
s_logger.error(details, e);
} catch (Exception e) {
details = "Couldn't determine primary SR type " + e.getMessage();
s_logger.error(details, e);
}
if (primaryStorageSR != null) {
if (snapshotUUID != null) {
VDI snapshotVDI = getVDIbyUuid(conn, snapshotUUID);
if (snapshotVDI != null) {
destroyVDI(conn, snapshotVDI);
}
}
}
URI uri = null;
try {
uri = new URI(secondaryStoragePoolURL);
} catch (URISyntaxException e) {
details = "Error finding the secondary storage URL" + e.getMessage();
s_logger.error(details, e);
}
if (uri != null) {
String secondaryStorageMountPath = uri.getHost() + ":" + uri.getPath();
success = deleteSnapshotsDir(conn, dcId, accountId, volumeId, secondaryStorageMountPath);
if (success) {
details = "Successfully deleted snapshotsDir for volume: " + volumeId;
s_logger.debug(details);
} else {
details = "Failed to delete snapshotsDir for volume: " + volumeId;
s_logger.warn(details);
}
}
return new Answer(cmd, success, details);
}
protected VM getVM(Connection conn, String vmName) {
// Look up VMs with the specified name

View File

@ -41,6 +41,7 @@ import com.cloud.agent.api.CheckHealthAnswer;
import com.cloud.agent.api.CheckHealthCommand;
import com.cloud.agent.api.Command;
import com.cloud.agent.api.ComputeChecksumCommand;
import com.cloud.agent.api.DeleteSnapshotBackupCommand;
import com.cloud.agent.api.DeleteSnapshotsDirCommand;
import com.cloud.agent.api.GetStorageStatsAnswer;
import com.cloud.agent.api.GetStorageStatsCommand;
@ -205,11 +206,8 @@ public class NfsSecondaryStorageResource extends ServerResourceBase implements S
Long volumeId = cmd.getVolumeId();
try {
String parent = getRootDir(secondaryStorageURL);
String lPath = parent + "/snapshots/" + String.valueOf(accountId) + "/" + String.valueOf(volumeId);
Script command = new Script("/bin/bash", s_logger);
command.add("-c");
command.add("rm -f " + lPath + "/*");
String result = command.execute();
String lPath = parent + "/snapshots/" + String.valueOf(accountId) + "/" + String.valueOf(volumeId) + "/*";
String result = deleteLocalFile(lPath);
if (result != null) {
String errMsg = "failed to delete all snapshots " + lPath + " , err=" + result;
s_logger.warn(errMsg);
@ -357,7 +355,52 @@ public class NfsSecondaryStorageResource extends ServerResourceBase implements S
}
}
protected Answer execute(final DeleteSnapshotBackupCommand cmd) {
String secondaryStorageURL = cmd.getSecondaryStoragePoolURL();
Long accountId = cmd.getAccountId();
Long volumeId = cmd.getVolumeId();
String name = cmd.getSnapshotUuid();
try {
SwiftTO swift = cmd.getSwift();
if (swift == null) {
String parent = getRootDir(secondaryStorageURL);
String filename;
if (cmd.isAll()) {
filename = "*";
} else {
filename = "*" + name + "*";
}
String lPath = parent + "/snapshots/" + String.valueOf(accountId) + "/" + String.valueOf(volumeId) + "/" + filename;
String result = deleteLocalFile(lPath);
if (result != null) {
String errMsg = "failed to delete snapshot " + lPath + " , err=" + result;
s_logger.warn(errMsg);
return new Answer(cmd, false, errMsg);
}
} else {
String filename;
if (cmd.isAll()) {
filename = "";
} else {
filename = name;
}
String result = swiftDelete(swift, volumeId.toString(), filename);
if (result != null) {
String errMsg = "failed to delete snapshot " + filename + " , err=" + result;
s_logger.warn(errMsg);
return new Answer(cmd, false, errMsg);
}
}
return new Answer(cmd, true, "success");
} catch (Exception e) {
String errMsg = cmd + " Command failed due to " + e.toString();
s_logger.warn(errMsg, e);
return new Answer(cmd, false, errMsg);
}
}
private Answer execute(ListTemplateCommand cmd) {
if (!_inSystemVM){
return new Answer(cmd, true, null);
@ -419,6 +462,19 @@ public class NfsSecondaryStorageResource extends ServerResourceBase implements S
return null;
}
private String deleteLocalFile(String fullPath) {
Script command = new Script("/bin/bash", s_logger);
command.add("-c");
command.add("rm -f " + fullPath);
String result = command.execute();
if (result != null) {
String errMsg = "Failed to delete file " + fullPath + ", err=" + result;
s_logger.warn(errMsg);
return errMsg;
}
return null;
}
public String allowOutgoingOnPrivate(String destCidr) {
Script command = new Script("/bin/bash", s_logger);

View File

@ -12,8 +12,6 @@ import com.cloud.agent.api.Command;
import com.cloud.agent.api.CreatePrivateTemplateFromSnapshotCommand;
import com.cloud.agent.api.CreatePrivateTemplateFromVolumeCommand;
import com.cloud.agent.api.CreateVolumeFromSnapshotCommand;
import com.cloud.agent.api.DeleteSnapshotBackupCommand;
import com.cloud.agent.api.DeleteSnapshotsDirCommand;
import com.cloud.agent.api.storage.CopyVolumeCommand;
import com.cloud.agent.api.storage.PrimaryStorageDownloadCommand;
import com.cloud.hypervisor.vmware.manager.VmwareHostService;
@ -56,10 +54,6 @@ public class VmwareSecondaryStorageResourceHandler implements SecondaryStorageRe
answer = execute((PrimaryStorageDownloadCommand)cmd);
} else if(cmd instanceof BackupSnapshotCommand) {
answer = execute((BackupSnapshotCommand)cmd);
} else if(cmd instanceof DeleteSnapshotsDirCommand) {
answer = execute((DeleteSnapshotsDirCommand)cmd);
} else if(cmd instanceof DeleteSnapshotBackupCommand) {
answer = execute((DeleteSnapshotBackupCommand)cmd);
} else if(cmd instanceof CreatePrivateTemplateFromVolumeCommand) {
answer = execute((CreatePrivateTemplateFromVolumeCommand)cmd);
} else if(cmd instanceof CreatePrivateTemplateFromSnapshotCommand) {
@ -98,22 +92,6 @@ public class VmwareSecondaryStorageResourceHandler implements SecondaryStorageRe
return _storageMgr.execute(this, cmd);
}
private Answer execute(DeleteSnapshotsDirCommand cmd) {
if (s_logger.isDebugEnabled()) {
s_logger.debug("Executing resource DeleteSnapshotsDirCommand: " + _gson.toJson(cmd));
}
return _storageMgr.execute(this, cmd);
}
private Answer execute(DeleteSnapshotBackupCommand cmd) {
if (s_logger.isDebugEnabled()) {
s_logger.debug("Executing resource DeleteSnapshotBackupCommand: " + _gson.toJson(cmd));
}
return _storageMgr.execute(this, cmd);
}
private Answer execute(CreatePrivateTemplateFromVolumeCommand cmd) {
if (s_logger.isDebugEnabled()) {
s_logger.debug("Executing resource CreatePrivateTemplateFromVolumeCommand: " + _gson.toJson(cmd));

View File

@ -15,16 +15,14 @@ import com.cloud.agent.api.Command;
import com.cloud.agent.api.CreatePrivateTemplateFromSnapshotCommand;
import com.cloud.agent.api.CreatePrivateTemplateFromVolumeCommand;
import com.cloud.agent.api.CreateVolumeFromSnapshotCommand;
import com.cloud.agent.api.DeleteSnapshotBackupCommand;
import com.cloud.agent.api.DeleteSnapshotsDirCommand;
import com.cloud.agent.api.storage.CopyVolumeCommand;
import com.cloud.agent.api.storage.PrimaryStorageDownloadCommand;
import com.cloud.agent.api.to.VirtualMachineTO;
import com.cloud.cluster.CheckPointManager;
import com.cloud.cluster.ClusterManager;
import com.cloud.host.HostVO;
import com.cloud.host.dao.HostDetailsDao;
import com.cloud.host.dao.HostDao;
import com.cloud.host.dao.HostDetailsDao;
import com.cloud.hypervisor.Hypervisor.HypervisorType;
import com.cloud.hypervisor.HypervisorGuru;
import com.cloud.hypervisor.HypervisorGuruBase;
@ -121,8 +119,6 @@ public class VMwareGuru extends HypervisorGuruBase implements HypervisorGuru {
if(cmd instanceof PrimaryStorageDownloadCommand ||
cmd instanceof BackupSnapshotCommand ||
cmd instanceof DeleteSnapshotsDirCommand ||
cmd instanceof DeleteSnapshotBackupCommand ||
cmd instanceof CreatePrivateTemplateFromVolumeCommand ||
cmd instanceof CreatePrivateTemplateFromSnapshotCommand ||
cmd instanceof CopyVolumeCommand ||

View File

@ -655,7 +655,7 @@ public class StorageManagerImpl implements StorageManager, StorageService, Manag
s_logger.error(basicErrMsg);
} finally {
if (snapshot.getSwiftId() != null) {
_snapshotMgr.deleteSnapshotsForVolume (secondaryStoragePoolUrl, dcId, accountId, volumeId);
_snapshotMgr.deleteSnapshotsDirForVolume(secondaryStoragePoolUrl, dcId, accountId, volumeId);
}
_snapshotDao.unlockFromLockTable(snapshotId.toString());
}

View File

@ -137,4 +137,6 @@ public interface SnapshotManager {
String getSecondaryStorageURL(SnapshotVO snapshot);
void deleteSnapshotsForVolume (String secondaryStoragePoolUrl, Long dcId, Long accountId, Long volumeId );
void deleteSnapshotsDirForVolume(String secondaryStoragePoolUrl, Long dcId, Long accountId, Long volumeId);
}

View File

@ -509,14 +509,32 @@ public class SnapshotManagerImpl implements SnapshotManager, SnapshotService, Ma
@Override
public void deleteSnapshotsForVolume (String secondaryStoragePoolUrl, Long dcId, Long accountId, Long volumeId ){
DeleteSnapshotsDirCommand cmd = new DeleteSnapshotsDirCommand("", secondaryStoragePoolUrl, dcId, accountId, volumeId, "");
SwiftVO swiftVO = _swiftDao.findById(1L);
SwiftTO swift = null;
if ( swiftVO != null ) {
swift = toSwiftTO(swiftVO);
}
DeleteSnapshotBackupCommand cmd = new DeleteSnapshotBackupCommand(swift, secondaryStoragePoolUrl, dcId, accountId, volumeId, null, true);
try {
Answer ans = _agentMgr.sendToSSVM(dcId, cmd);
if ( ans == null || !ans.getResult() ) {
s_logger.warn("DeleteSnapshotsDirCommand failed due to " + ans.getDetails() + " volume id: " + volumeId );
s_logger.warn("DeleteSnapshotBackupCommand failed due to " + ans.getDetails() + " volume id: " + volumeId);
}
} catch (Exception e) {
s_logger.warn("DeleteSnapshotsDirCommand failed due to" + e.toString() + " volume id: " + volumeId );
s_logger.warn("DeleteSnapshotBackupCommand failed due to" + e.toString() + " volume id: " + volumeId);
}
}
@Override
public void deleteSnapshotsDirForVolume(String secondaryStoragePoolUrl, Long dcId, Long accountId, Long volumeId) {
DeleteSnapshotsDirCommand cmd = new DeleteSnapshotsDirCommand(secondaryStoragePoolUrl, dcId, accountId, volumeId);
try {
Answer ans = _agentMgr.sendToSSVM(dcId, cmd);
if (ans == null || !ans.getResult()) {
s_logger.warn("DeleteSnapshotsDirCommand failed due to " + ans.getDetails() + " volume id: " + volumeId);
}
} catch (Exception e) {
s_logger.warn("DeleteSnapshotsDirCommand failed due to" + e.toString() + " volume id: " + volumeId);
}
}
@ -842,7 +860,6 @@ public class SnapshotManagerImpl implements SnapshotManager, SnapshotService, Ma
if (snapshot == null) {
throw new CloudRuntimeException("Destroying snapshot " + snapshotId + " backup failed due to unable to find snapshot ");
}
String secondaryStoragePoolUrl = getSecondaryStorageURL(snapshot);
Long dcId = snapshot.getDataCenterId();
Long accountId = snapshot.getAccountId();
@ -853,16 +870,13 @@ public class SnapshotManagerImpl implements SnapshotManager, SnapshotService, Ma
if (backupOfSnapshot == null) {
return true;
}
DeleteSnapshotBackupCommand cmd = new DeleteSnapshotBackupCommand(null, secondaryStoragePoolUrl, dcId, accountId, volumeId, backupOfSnapshot, snapshot.getName());
snapshot.setBackupSnapshotId(null);
_snapshotDao.update(snapshotId, snapshot);
Answer answer = _agentMgr.sendTo(dcId, hvType, cmd);
SwiftTO swift = getSwiftTO();
DeleteSnapshotBackupCommand cmd = new DeleteSnapshotBackupCommand(swift, secondaryStoragePoolUrl, dcId, accountId, volumeId, backupOfSnapshot, false);
Answer answer = _agentMgr.sendToSSVM(dcId, cmd);
if ((answer != null) && answer.getResult()) {
// This is not the last snapshot.
snapshot.setBackupSnapshotId(null);
_snapshotDao.update(snapshotId, snapshot);
success = true;
details = "Successfully deleted snapshot " + snapshotId + " for volumeId: " + volumeId;
s_logger.debug(details);
@ -1022,6 +1036,13 @@ public class SnapshotManagerImpl implements SnapshotManager, SnapshotService, Ma
return _snapshotDao.search(sc, searchFilter);
}
private SwiftTO getSwiftTO() {
SwiftVO swiftVO = _swiftDao.findById(1l);
if (swiftVO != null) {
return toSwiftTO(swiftVO);
}
return null;
}
@Override
public boolean deleteSnapshotDirsForAccount(long accountId) {
@ -1036,33 +1057,43 @@ public class SnapshotManagerImpl implements SnapshotManager, SnapshotService, Ma
}
Long volumeId = volume.getId();
Long dcId = volume.getDataCenterId();
String primaryStoragePoolNameLabel = _storageMgr.getPrimaryStorageNameLabel(volume);
if (_snapshotDao.listByVolumeIdIncludingRemoved(volumeId).isEmpty()) {
// This volume doesn't have any snapshots. Nothing do delete.
continue;
}
List<HostVO> ssHosts = _hostDao.listSecondaryStorageHosts(dcId);
for ( HostVO ssHost : ssHosts ) {
DeleteSnapshotsDirCommand cmd = new DeleteSnapshotsDirCommand(primaryStoragePoolNameLabel, ssHost.getStorageUrl(), dcId, accountId, volumeId, volume.getPath());
Answer answer = null;
Long poolId = volume.getPoolId();
if (poolId != null) {
// Retry only once for this command. There's low chance of failure because of a connection problem.
SwiftTO swift = getSwiftTO();
if (swift == null) {
for (HostVO ssHost : ssHosts) {
DeleteSnapshotBackupCommand cmd = new DeleteSnapshotBackupCommand(null, ssHost.getStorageUrl(), dcId, accountId, volumeId, "", true);
Answer answer = null;
try {
answer = _storageMgr.sendToPool(poolId, cmd);
} catch (StorageUnavailableException e) {
answer = _agentMgr.sendToSSVM(dcId, cmd);
} catch (Exception e) {
s_logger.warn("Failed to delete all snapshot for volume " + volumeId + " on secondary storage " + ssHost.getStorageUrl());
}
if ((answer != null) && answer.getResult()) {
s_logger.debug("Deleted all snapshots for volume: " + volumeId + " under account: " + accountId);
} else {
success = false;
if (answer != null) {
s_logger.error(answer.getDetails());
}
}
} else {
s_logger.info("Pool id for volume id: " + volumeId + " belonging to account id: " + accountId + " is null. Assuming the snapshotsDir for the account has already been deleted");
}
if (success) {
// SnapshotsDir has been deleted for the volumes so far.
success = (answer != null) && answer.getResult();
if (success) {
s_logger.debug("Deleted snapshotsDir for volume: " + volumeId + " under account: " + accountId);
} else if (answer != null) {
} else {
DeleteSnapshotBackupCommand cmd = new DeleteSnapshotBackupCommand(swift, "", dcId, accountId, volumeId, "", true);
Answer answer = null;
try {
answer = _agentMgr.sendToSSVM(dcId, cmd);
} catch (Exception e) {
s_logger.warn("Failed to delete all snapshot for volume " + volumeId + " on swift");
}
if ((answer != null) && answer.getResult()) {
s_logger.debug("Deleted all snapshots for volume: " + volumeId + " under account: " + accountId);
} else {
success = false;
if (answer != null) {
s_logger.error(answer.getDetails());
}
}