diff --git a/backend/manager/modules/bll/src/main/java/org/ovirt/engine/core/bll/storage/disk/image/RemoveImageCommand.java b/backend/manager/modules/bll/src/main/java/org/ovirt/engine/core/bll/storage/disk/image/RemoveImageCommand.java index 0d9e767ef63..aa9ec914372 100644 --- a/backend/manager/modules/bll/src/main/java/org/ovirt/engine/core/bll/storage/disk/image/RemoveImageCommand.java +++ b/backend/manager/modules/bll/src/main/java/org/ovirt/engine/core/bll/storage/disk/image/RemoveImageCommand.java @@ -16,12 +16,15 @@ import org.ovirt.engine.core.bll.NonTransactiveCommandAttribute; import org.ovirt.engine.core.bll.context.CommandContext; import org.ovirt.engine.core.bll.storage.domain.PostDeleteActionHandler; +import org.ovirt.engine.core.bll.storage.utils.VdsCommandsHelper; import org.ovirt.engine.core.common.AuditLogType; import org.ovirt.engine.core.common.VdcObjectType; import org.ovirt.engine.core.common.action.ActionType; import org.ovirt.engine.core.common.action.RemoveImageParameters; import org.ovirt.engine.core.common.asynctasks.AsyncTaskType; import org.ovirt.engine.core.common.businessentities.Snapshot; +import org.ovirt.engine.core.common.businessentities.VDS; +import org.ovirt.engine.core.common.businessentities.VDSStatus; import org.ovirt.engine.core.common.businessentities.VM; import org.ovirt.engine.core.common.businessentities.VmDeviceId; import org.ovirt.engine.core.common.businessentities.storage.DiskImage; @@ -30,6 +33,7 @@ import org.ovirt.engine.core.common.errors.EngineError; import org.ovirt.engine.core.common.errors.EngineException; import org.ovirt.engine.core.common.vdscommands.DeleteImageGroupVDSCommandParameters; +import org.ovirt.engine.core.common.vdscommands.DeleteImageUnusedLinksVDSCommandParameters; import org.ovirt.engine.core.common.vdscommands.GetImagesListVDSCommandParameters; import org.ovirt.engine.core.common.vdscommands.VDSCommandType; import org.ovirt.engine.core.common.vdscommands.VDSReturnValue; @@ -42,6 +46,7 @@ import org.ovirt.engine.core.dao.ImageDao; import org.ovirt.engine.core.dao.ImageStorageDomainMapDao; import org.ovirt.engine.core.dao.SnapshotDao; +import org.ovirt.engine.core.dao.VdsDao; import org.ovirt.engine.core.dao.VmDao; import org.ovirt.engine.core.dao.VmDeviceDao; import org.ovirt.engine.core.utils.ovf.OvfManager; @@ -85,6 +90,10 @@ public class RemoveImageCommand extends BaseIma @Inject private VmDao vmDao; + @Inject + private VdsCommandsHelper vdsCommandsHelper; + @Inject + private VdsDao vdsDao; public RemoveImageCommand(T parameters, CommandContext cmdContext) { super(parameters, cmdContext); @@ -335,11 +344,48 @@ protected VDSReturnValue performDeleteImageVdsmOperation() { ImageStatus.ILLEGAL, getCompensationContext()); } - return runVdsCommand(VDSCommandType.DeleteImageGroup, + final VDSReturnValue vdsReturnValue = runVdsCommand(VDSCommandType.DeleteImageGroup, postDeleteActionHandler.fixParameters( new DeleteImageGroupVDSCommandParameters(getDiskImage().getStoragePoolId(), getStorageDomainId(), getDiskImage().getId(), getDiskImage().isWipeAfterDelete(), getStorageDomain().getDiscardAfterDelete(), getParameters().isForceDelete()))); + + if (vdsReturnValue.getSucceeded()) { + performDeleteImageUnusedLinks(); + } + + return vdsReturnValue; + } + + protected void performDeleteImageUnusedLinks() { + List vdsForExecute = vdsDao.getAllForStoragePoolAndStatus(getDiskImage().getStoragePoolId(), VDSStatus.Up) + .stream() + .map(VDS::getId) + .collect(Collectors.toList()); + + log.info("Deleting unused image links on hosts: [{}].", vdsForExecute); + + for (Guid vdsId : vdsForExecute) { + try { + log.info("Start deleting unused image links on host '{}'. Image '{}', storage domain '{}', " + + "storage pool '{}'", + vdsId, getDiskImage().getId(), getStorageDomainId(), getDiskImage().getStoragePoolId()); + + vdsCommandsHelper.runVdsCommandWithoutFailover( + VDSCommandType.DeleteImageUnusedLinks, + new DeleteImageUnusedLinksVDSCommandParameters(vdsId, getStorageDomainId(), + getDiskImage().getStoragePoolId(), getDiskImage().getId()), + getDiskImage().getStoragePoolId(), null); + + log.info("Unused image links were successfully deleted on host '{}'. Image '{}', storage domain '{}', " + + "storage pool '{}'", + vdsId, getDiskImage().getId(), getStorageDomainId(), getDiskImage().getStoragePoolId()); + } catch (EngineException e) { + log.error("Error while deleting unused image links on host '{}'. Image '{}', storage domain '{}', " + + "storage pool '{}', exception = {}", + vdsId, getDiskImage().getId(), getStorageDomainId(), getDiskImage().getStoragePoolId(), e); + } + } } } diff --git a/backend/manager/modules/common/src/main/java/org/ovirt/engine/core/common/vdscommands/DeleteImageUnusedLinksVDSCommandParameters.java b/backend/manager/modules/common/src/main/java/org/ovirt/engine/core/common/vdscommands/DeleteImageUnusedLinksVDSCommandParameters.java new file mode 100644 index 00000000000..e1af4c1d0b8 --- /dev/null +++ b/backend/manager/modules/common/src/main/java/org/ovirt/engine/core/common/vdscommands/DeleteImageUnusedLinksVDSCommandParameters.java @@ -0,0 +1,64 @@ +package org.ovirt.engine.core.common.vdscommands; + +import org.ovirt.engine.core.common.utils.ToStringBuilder; +import org.ovirt.engine.core.compat.Guid; + +public class DeleteImageUnusedLinksVDSCommandParameters extends VdsIdVDSCommandParametersBase { + + /** + * ID storage domain. + */ + private Guid sdUUID; + + /** + * ID storage pool. + */ + private Guid spUUID; + + /** + * ID image. + */ + private Guid imgUUID; + + public DeleteImageUnusedLinksVDSCommandParameters() { + } + + public DeleteImageUnusedLinksVDSCommandParameters(Guid vdsId, Guid sdUUID, Guid spUUID, Guid imgUUID) { + super(vdsId); + this.sdUUID = sdUUID; + this.spUUID = spUUID; + this.imgUUID = imgUUID; + } + + public Guid getSdUUID() { + return sdUUID; + } + + public void setSdUUID(Guid sdUUID) { + this.sdUUID = sdUUID; + } + + public Guid getSpUUID() { + return spUUID; + } + + public void setSpUUID(Guid spUUID) { + this.spUUID = spUUID; + } + + public Guid getImgUUID() { + return imgUUID; + } + + public void setImgUUID(Guid imgUUID) { + this.imgUUID = imgUUID; + } + + @Override + protected ToStringBuilder appendAttributes(ToStringBuilder tsb) { + return super.appendAttributes(tsb) + .append("sdUUID", getSdUUID()) + .append("spUUID", getSpUUID()) + .append("imgUUID", getImgUUID()); + } +} diff --git a/backend/manager/modules/common/src/main/java/org/ovirt/engine/core/common/vdscommands/VDSCommandType.java b/backend/manager/modules/common/src/main/java/org/ovirt/engine/core/common/vdscommands/VDSCommandType.java index 81a19572d62..87f559681a0 100644 --- a/backend/manager/modules/common/src/main/java/org/ovirt/engine/core/common/vdscommands/VDSCommandType.java +++ b/backend/manager/modules/common/src/main/java/org/ovirt/engine/core/common/vdscommands/VDSCommandType.java @@ -90,6 +90,7 @@ public enum VDSCommandType { GetStoragePoolInfo("org.ovirt.engine.core.vdsbroker.irsbroker"), DestroyStoragePool("org.ovirt.engine.core.vdsbroker.irsbroker"), DeleteImageGroup("org.ovirt.engine.core.vdsbroker.irsbroker"), + DeleteImageUnusedLinks("org.ovirt.engine.core.vdsbroker.vdsbroker"), MoveImageGroup("org.ovirt.engine.core.vdsbroker.irsbroker"), CloneImageGroupStructure("org.ovirt.engine.core.vdsbroker.irsbroker"), SyncImageGroupData("org.ovirt.engine.core.vdsbroker.irsbroker"), diff --git a/backend/manager/modules/vdsbroker/src/main/java/org/ovirt/engine/core/vdsbroker/jsonrpc/JsonRpcVdsServer.java b/backend/manager/modules/vdsbroker/src/main/java/org/ovirt/engine/core/vdsbroker/jsonrpc/JsonRpcVdsServer.java index bd771342b79..89b1f95ba31 100644 --- a/backend/manager/modules/vdsbroker/src/main/java/org/ovirt/engine/core/vdsbroker/jsonrpc/JsonRpcVdsServer.java +++ b/backend/manager/modules/vdsbroker/src/main/java/org/ovirt/engine/core/vdsbroker/jsonrpc/JsonRpcVdsServer.java @@ -2695,4 +2695,16 @@ public ScreenshotInfoReturn createScreenshot(String vmId) { Map response = new FutureMap(this.client, request).withIgnoreResponseKey(); return new ScreenshotInfoReturn(response); } + + @Override + public StatusOnlyReturn deleteImageUnusedLinks(String sdUUID, String spUUID, String imgUUID) { + JsonRpcRequest request = + new RequestBuilder("Image.deleteUnusedLinks") + .withParameter("storagedomainID", sdUUID) + .withParameter("storagepoolID", spUUID) + .withParameter("imageID", imgUUID) + .build(); + Map response = new FutureMap(this.client, request); + return new StatusOnlyReturn(response); + } } diff --git a/backend/manager/modules/vdsbroker/src/main/java/org/ovirt/engine/core/vdsbroker/vdsbroker/DeleteImageUnusedLinksVDSCommand.java b/backend/manager/modules/vdsbroker/src/main/java/org/ovirt/engine/core/vdsbroker/vdsbroker/DeleteImageUnusedLinksVDSCommand.java new file mode 100644 index 00000000000..5586794f078 --- /dev/null +++ b/backend/manager/modules/vdsbroker/src/main/java/org/ovirt/engine/core/vdsbroker/vdsbroker/DeleteImageUnusedLinksVDSCommand.java @@ -0,0 +1,39 @@ +package org.ovirt.engine.core.vdsbroker.vdsbroker; + +import org.ovirt.engine.core.common.vdscommands.DeleteImageUnusedLinksVDSCommandParameters; + +public class DeleteImageUnusedLinksVDSCommand

+ extends VdsBrokerCommand

{ + + protected StatusOnlyReturn statusReturn; + + public DeleteImageUnusedLinksVDSCommand(P parameters) { + super(parameters); + } + + @Override + protected Status getReturnStatus() { + return statusReturn.status; + } + + @Override + protected Object getReturnValueFromBroker() { + return statusReturn; + } + + @Override + public Object getReturnValue() { + return statusReturn; + } + + @Override + protected void executeVdsBrokerCommand() { + DeleteImageUnusedLinksVDSCommandParameters params = getParameters(); + statusReturn = getBroker().deleteImageUnusedLinks( + params.getSdUUID().toString(), + params.getSpUUID().toString(), + params.getImgUUID().toString()); + + proceedProxyReturnValue(); + } +} diff --git a/backend/manager/modules/vdsbroker/src/main/java/org/ovirt/engine/core/vdsbroker/vdsbroker/IVdsServer.java b/backend/manager/modules/vdsbroker/src/main/java/org/ovirt/engine/core/vdsbroker/vdsbroker/IVdsServer.java index 05fc2073886..508bb953acd 100644 --- a/backend/manager/modules/vdsbroker/src/main/java/org/ovirt/engine/core/vdsbroker/vdsbroker/IVdsServer.java +++ b/backend/manager/modules/vdsbroker/src/main/java/org/ovirt/engine/core/vdsbroker/vdsbroker/IVdsServer.java @@ -610,4 +610,5 @@ StatusOnlyReturn glusterVolumeResetBrickCommitForce(String volumeName, ScreenshotInfoReturn createScreenshot(String vmId); + StatusOnlyReturn deleteImageUnusedLinks(String sdUUID, String spUUID, String imgUUID); } diff --git a/backend/manager/modules/vdsbroker/src/main/java/org/ovirt/engine/core/vdsbroker/vdsbroker/NullVdsServer.java b/backend/manager/modules/vdsbroker/src/main/java/org/ovirt/engine/core/vdsbroker/vdsbroker/NullVdsServer.java index f157ce32875..f5b151670fd 100644 --- a/backend/manager/modules/vdsbroker/src/main/java/org/ovirt/engine/core/vdsbroker/vdsbroker/NullVdsServer.java +++ b/backend/manager/modules/vdsbroker/src/main/java/org/ovirt/engine/core/vdsbroker/vdsbroker/NullVdsServer.java @@ -1109,4 +1109,9 @@ public GlusterVolumeGlobalOptionsInfoReturn glusterVolumeGlobalOptionsGet() { public ScreenshotInfoReturn createScreenshot(String vmId) { return null; } + + @Override + public StatusOnlyReturn deleteImageUnusedLinks(String sdUUID, String spUUID, String imgUUID) { + return null; + } }