Shubhendu Tripathi has uploaded a new change for review. Change subject: gluster: Restore volume snapshot with georep case ......................................................................
gluster: Restore volume snapshot with georep case Enhanced the code to restore a gluster volume to the state of volume snapshot if there is an acive geo-replication available for the volume. Change-Id: I0eccbcd4aa3e218ba0d910bd9150bdb0baa2db68 Signed-off-by: Shubhendu Tripathi <[email protected]> --- M backend/manager/modules/bll/src/main/java/org/ovirt/engine/core/bll/gluster/DeleteGlusterVolumeSnapshotCommand.java M backend/manager/modules/bll/src/main/java/org/ovirt/engine/core/bll/gluster/GlusterVolumeSnapshotCommandBase.java M backend/manager/modules/bll/src/main/java/org/ovirt/engine/core/bll/gluster/RestoreGlusterVolumeSnapshotCommand.java M backend/manager/modules/bll/src/main/java/org/ovirt/engine/core/bll/gluster/StartGlusterVolumeCommand.java M backend/manager/modules/bll/src/main/java/org/ovirt/engine/core/bll/gluster/StopGlusterVolumeCommand.java M backend/manager/modules/vdsbroker/src/main/java/org/ovirt/engine/core/vdsbroker/jsonrpc/JsonRpcVdsServer.java 6 files changed, 198 insertions(+), 57 deletions(-) git pull ssh://gerrit.ovirt.org:29418/ovirt-engine refs/changes/50/38150/1 diff --git a/backend/manager/modules/bll/src/main/java/org/ovirt/engine/core/bll/gluster/DeleteGlusterVolumeSnapshotCommand.java b/backend/manager/modules/bll/src/main/java/org/ovirt/engine/core/bll/gluster/DeleteGlusterVolumeSnapshotCommand.java index b2e25fa..1eec54b 100644 --- a/backend/manager/modules/bll/src/main/java/org/ovirt/engine/core/bll/gluster/DeleteGlusterVolumeSnapshotCommand.java +++ b/backend/manager/modules/bll/src/main/java/org/ovirt/engine/core/bll/gluster/DeleteGlusterVolumeSnapshotCommand.java @@ -20,7 +20,7 @@ @Override public void executeCommand() { VDSReturnValue retVal = - runVdsCommand(VDSCommandType.DeleteGlusterVolume, + runVdsCommand(VDSCommandType.DeleteGlusterVolumeSnapshot, new GlusterVolumeSnapshotActionVDSParameters(getUpServer().getId(), getGlusterVolumeName(), getParameters().getSnapshotName())); diff --git a/backend/manager/modules/bll/src/main/java/org/ovirt/engine/core/bll/gluster/GlusterVolumeSnapshotCommandBase.java b/backend/manager/modules/bll/src/main/java/org/ovirt/engine/core/bll/gluster/GlusterVolumeSnapshotCommandBase.java index 2fbfeba..db969f4 100644 --- a/backend/manager/modules/bll/src/main/java/org/ovirt/engine/core/bll/gluster/GlusterVolumeSnapshotCommandBase.java +++ b/backend/manager/modules/bll/src/main/java/org/ovirt/engine/core/bll/gluster/GlusterVolumeSnapshotCommandBase.java @@ -1,5 +1,8 @@ package org.ovirt.engine.core.bll.gluster; +import java.util.HashMap; +import java.util.Map; + import org.ovirt.engine.core.common.action.gluster.GlusterVolumeSnapshotActionParameters; import org.ovirt.engine.core.common.businessentities.gluster.GlusterVolumeSnapshotEntity; import org.ovirt.engine.core.common.constants.gluster.GlusterConstants; @@ -14,6 +17,13 @@ } @Override + public Map<String, String> getCustomValues() { + Map<String, String> map = new HashMap<>(); + map.put(GlusterConstants.VOLUME_SNAPSHOT_NAME, getParameters().getSnapshotName()); + return map; + } + + @Override protected void setActionMessageParameters() { addCustomValue(GlusterConstants.VOLUME_SNAPSHOT_NAME, getParameters().getSnapshotName()); } diff --git a/backend/manager/modules/bll/src/main/java/org/ovirt/engine/core/bll/gluster/RestoreGlusterVolumeSnapshotCommand.java b/backend/manager/modules/bll/src/main/java/org/ovirt/engine/core/bll/gluster/RestoreGlusterVolumeSnapshotCommand.java index 260218d..42e70bc 100644 --- a/backend/manager/modules/bll/src/main/java/org/ovirt/engine/core/bll/gluster/RestoreGlusterVolumeSnapshotCommand.java +++ b/backend/manager/modules/bll/src/main/java/org/ovirt/engine/core/bll/gluster/RestoreGlusterVolumeSnapshotCommand.java @@ -7,16 +7,17 @@ import org.ovirt.engine.core.common.action.VdcActionType; import org.ovirt.engine.core.common.action.VdcReturnValueBase; import org.ovirt.engine.core.common.action.gluster.GlusterVolumeActionParameters; +import org.ovirt.engine.core.common.action.gluster.GlusterVolumeGeoRepSessionParameters; import org.ovirt.engine.core.common.action.gluster.GlusterVolumeSnapshotActionParameters; import org.ovirt.engine.core.common.businessentities.VDS; import org.ovirt.engine.core.common.businessentities.gluster.GlusterGeoRepSession; import org.ovirt.engine.core.common.businessentities.gluster.GlusterStatus; import org.ovirt.engine.core.common.businessentities.gluster.GlusterVolumeEntity; -import org.ovirt.engine.core.common.businessentities.gluster.GlusterVolumeSnapshotEntity; import org.ovirt.engine.core.common.errors.VdcBllMessages; import org.ovirt.engine.core.common.vdscommands.VDSCommandType; import org.ovirt.engine.core.common.vdscommands.VDSReturnValue; import org.ovirt.engine.core.common.vdscommands.gluster.GlusterVolumeSnapshotActionVDSParameters; +import org.ovirt.engine.core.compat.Guid; public class RestoreGlusterVolumeSnapshotCommand extends GlusterVolumeSnapshotCommandBase<GlusterVolumeSnapshotActionParameters> { private List<GlusterGeoRepSession> georepSessions; @@ -31,12 +32,84 @@ addCanDoActionMessage(VdcBllMessages.VAR__ACTION__RESTORE); } - @Override - public void executeCommand() { - for (GlusterGeoRepSession session : georepSessions) { + private boolean pauseGeoReplicationSessions(List<GlusterGeoRepSession> geoRepSessions) { + for (GlusterGeoRepSession session : geoRepSessions) { GlusterVolumeEntity slaveVolume = getDbFacade().getGlusterVolumeDao().getById(session.getSlaveVolumeId()); if (slaveVolume == null) { - // continue with other sessions and restore the volumes + // continue with other sessions and try to pause + continue; + } + + VdcReturnValueBase retVal = runInternalAction(VdcActionType.PauseGlusterVolumeGeoRepSession, + new GlusterVolumeGeoRepSessionParameters(getGlusterVolumeId(), session.getId())); + + if (!retVal.getSucceeded()) { + handleVdsError(AuditLogType.GLUSTER_VOLUME_GEO_REP_PAUSE_FAILED, retVal.getExecuteFailedMessages() + .toString()); + setSucceeded(false); + return false; + } + } + + return true; + } + + private boolean stopVolume(Guid volumeId) { + GlusterVolumeEntity volume = getGlusterVolumeDao().getById(volumeId); + if (volume != null && volume.getStatus() == GlusterStatus.UP) { + VdcReturnValueBase retVal = + runInternalAction(VdcActionType.StopGlusterVolume, + new GlusterVolumeActionParameters(volumeId, true)); + if (!retVal.getSucceeded()) { + handleVdsError(AuditLogType.GLUSTER_VOLUME_STOP_FAILED, retVal.getExecuteFailedMessages().toString()); + setSucceeded(false); + return false; + } + } + + return true; + } + + private boolean stopSlaveVolumes(List<GlusterGeoRepSession> geoRepSessions) { + for (GlusterGeoRepSession session : geoRepSessions) { + GlusterVolumeEntity slaveVolume = getDbFacade().getGlusterVolumeDao().getById(session.getSlaveVolumeId()); + if (slaveVolume == null) { + // continue with other sessions and try to stop + continue; + } + + if (!stopVolume(slaveVolume.getId())) { + return false; + } + } + + return true; + } + + private boolean restoreVolumeToSnapshot(Guid upServerId, Guid volumeId, String snapshotName) { + GlusterVolumeEntity volume = getGlusterVolumeDao().getById(volumeId); + + if (volume != null) { + VDSReturnValue retVal = + runVdsCommand(VDSCommandType.RestoreGlusterVolumeSnapshot, + new GlusterVolumeSnapshotActionVDSParameters(upServerId, volume.getName(), snapshotName)); + if (!retVal.getSucceeded()) { + handleVdsError(AuditLogType.GLUSTER_VOLUME_SNAPSHOT_RESTORE_FAILED, retVal.getVdsError().getMessage()); + setSucceeded(false); + return false; + } else { + getGlusterVolumeSnapshotDao().removeByName(volumeId, snapshotName); + } + } + + return true; + } + + private boolean restoreSlaveVolumesToSnapshot(List<GlusterGeoRepSession> geoRepSessions, String snapshotName) { + for (GlusterGeoRepSession session : geoRepSessions) { + GlusterVolumeEntity slaveVolume = getDbFacade().getGlusterVolumeDao().getById(session.getSlaveVolumeId()); + if (slaveVolume == null) { + // continue with other sessions and try to pause continue; } @@ -45,69 +118,117 @@ handleVdsError(AuditLogType.GLUSTER_VOLUME_SNAPSHOT_RESTORE_FAILED, "No up server found in slave cluster of geo-rep session"); setSucceeded(false); - return; + return false; } - // Bring down the remote volume and restore snapshot - if (slaveVolume.getStatus() == GlusterStatus.UP) { - VdcReturnValueBase volumeDownRetVal = - runInternalAction(VdcActionType.StopGlusterVolume, - new GlusterVolumeActionParameters(slaveVolume.getId(), true)); - if (!volumeDownRetVal.getSucceeded()) { - handleVdsError(AuditLogType.GLUSTER_VOLUME_STOP_FAILED, slaveVolume.getName()); - setSucceeded(false); - return; - } else { - GlusterVolumeSnapshotEntity slaveVolumeSnapshot = - getGlusterVolumeSnapshotDao().getByName(slaveVolume.getId(), - getParameters().getSnapshotName()); - if (slaveVolumeSnapshot == null) { - handleVdsError(AuditLogType.GLUSTER_VOLUME_SNAPSHOT_RESTORE_FAILED, - "Unable to find snapshot for slave volume"); - setSucceeded(false); - return; - } - - VDSReturnValue slaveRestoreRetVal = - runVdsCommand(VDSCommandType.RestoreGlusterVolumeSnapshot, - new GlusterVolumeSnapshotActionVDSParameters(slaveUpServer.getId(), - slaveVolume.getName(), - slaveVolumeSnapshot.getSnapshotName())); - if (!slaveRestoreRetVal.getSucceeded()) { - handleVdsError(AuditLogType.GLUSTER_VOLUME_SNAPSHOT_RESTORE_FAILED, - slaveRestoreRetVal.getVdsError().getMessage()); - setSucceeded(false); - return; - } else { - getGlusterVolumeSnapshotDao().remove(slaveVolumeSnapshot.getId()); - } - } + if (!restoreVolumeToSnapshot(slaveUpServer.getId(), slaveVolume.getId(), getSnapshot().getSnapshotName())) { + return false; } } - VDSReturnValue retVal = - runVdsCommand(VDSCommandType.RestoreGlusterVolumeSnapshot, - new GlusterVolumeSnapshotActionVDSParameters(getUpServer().getId(), - getGlusterVolumeName(), - getParameters().getSnapshotName())); - setSucceeded(retVal.getSucceeded()); + return true; + } - if (!getSucceeded()) { - handleVdsError(AuditLogType.GLUSTER_VOLUME_SNAPSHOT_RESTORE_FAILED, retVal.getVdsError().getMessage()); - } else { - getGlusterVolumeSnapshotDao().remove(getSnapshot().getId()); - // TODO: Was discussed to mark the snapshot as restored and still maintain in engine + private boolean startVolume(Guid volumeId) { + VdcReturnValueBase retVal = + runInternalAction(VdcActionType.StartGlusterVolume, new GlusterVolumeActionParameters(volumeId, true)); + + if (!retVal.getSucceeded()) { + handleVdsError(AuditLogType.GLUSTER_VOLUME_START_FAILED, retVal.getExecuteFailedMessages().toString()); + setSucceeded(false); + return false; } + + return true; + } + + private boolean startSlaveVolumes(List<GlusterGeoRepSession> geoRepSessions) { + for (GlusterGeoRepSession session : geoRepSessions) { + GlusterVolumeEntity slaveVolume = getDbFacade().getGlusterVolumeDao().getById(session.getSlaveVolumeId()); + if (slaveVolume == null) { + // continue with other sessions and try to stop + continue; + } + + if (!startVolume(slaveVolume.getId())) { + return false; + } + } + + return true; + } + + private boolean resumeGeoRepSessions(List<GlusterGeoRepSession> geoRepSessions) { + for (GlusterGeoRepSession session : geoRepSessions) { + GlusterVolumeEntity slaveVolume = getDbFacade().getGlusterVolumeDao().getById(session.getSlaveVolumeId()); + if (slaveVolume == null) { + // continue with other sessions and try to pause + continue; + } + + VdcReturnValueBase retVal = runInternalAction(VdcActionType.ResumeGeoRepSession, + new GlusterVolumeGeoRepSessionParameters(getGlusterVolumeId(), session.getId())); + + if (!retVal.getSucceeded()) { + handleVdsError(AuditLogType.GLUSTER_VOLUME_GEO_REP_RESUME_FAILED, retVal.getExecuteFailedMessages() + .toString()); + setSucceeded(false); + return false; + } + } + + return true; + } + + @Override + public void executeCommand() { + // Pause the geo-replication session + if (!pauseGeoReplicationSessions(georepSessions)) { + return; + } + + // Stop the slave volumes + if (!stopSlaveVolumes(georepSessions)) { + return; + } + + // Restore the slave volumes to said the snapshot + if (!restoreSlaveVolumesToSnapshot(georepSessions, getParameters().getSnapshotName())) { + return; + } + + // Stop the master volume + if (!stopVolume(getGlusterVolumeId())) { + return; + } + + // Restore the master volume to the said snapshot + if (!restoreVolumeToSnapshot(upServer.getId(), getGlusterVolumeId(), getParameters().getSnapshotName())) { + return; + } + + // Start the slave volumes + if (!startSlaveVolumes(georepSessions)) { + return; + } + + // Start the master volume + if (!startVolume(getGlusterVolumeId())) { + return; + } + + // Resume the geo-replication sessions + if (!resumeGeoRepSessions(georepSessions)) { + return; + } + + setSucceeded(true); } @Override protected boolean canDoAction() { if (!super.canDoAction()) { return false; - } - - if (getGlusterVolume().getStatus() != GlusterStatus.DOWN) { - failCanDoAction(VdcBllMessages.ACTION_TYPE_FAILED_GLUSTER_VOLUME_IS_UP, getGlusterVolumeName()); } for (GlusterGeoRepSession session : georepSessions) { diff --git a/backend/manager/modules/bll/src/main/java/org/ovirt/engine/core/bll/gluster/StartGlusterVolumeCommand.java b/backend/manager/modules/bll/src/main/java/org/ovirt/engine/core/bll/gluster/StartGlusterVolumeCommand.java index 4f0936a..2b50232 100644 --- a/backend/manager/modules/bll/src/main/java/org/ovirt/engine/core/bll/gluster/StartGlusterVolumeCommand.java +++ b/backend/manager/modules/bll/src/main/java/org/ovirt/engine/core/bll/gluster/StartGlusterVolumeCommand.java @@ -1,6 +1,7 @@ package org.ovirt.engine.core.bll.gluster; import org.ovirt.engine.core.bll.NonTransactiveCommandAttribute; +import org.ovirt.engine.core.bll.context.CommandContext; import org.ovirt.engine.core.common.AuditLogType; import org.ovirt.engine.core.common.action.LockProperties; import org.ovirt.engine.core.common.action.LockProperties.Scope; @@ -23,6 +24,10 @@ super(params); } + public StartGlusterVolumeCommand(GlusterVolumeActionParameters params, CommandContext context) { + super(params, context); + } + @Override protected LockProperties applyLockProperties(LockProperties lockProperties) { return lockProperties.withScope(Scope.Execution).withWait(true); diff --git a/backend/manager/modules/bll/src/main/java/org/ovirt/engine/core/bll/gluster/StopGlusterVolumeCommand.java b/backend/manager/modules/bll/src/main/java/org/ovirt/engine/core/bll/gluster/StopGlusterVolumeCommand.java index b51e3a4..402d05c 100644 --- a/backend/manager/modules/bll/src/main/java/org/ovirt/engine/core/bll/gluster/StopGlusterVolumeCommand.java +++ b/backend/manager/modules/bll/src/main/java/org/ovirt/engine/core/bll/gluster/StopGlusterVolumeCommand.java @@ -1,6 +1,7 @@ package org.ovirt.engine.core.bll.gluster; import org.ovirt.engine.core.bll.NonTransactiveCommandAttribute; +import org.ovirt.engine.core.bll.context.CommandContext; import org.ovirt.engine.core.bll.gluster.tasks.GlusterTaskUtils; import org.ovirt.engine.core.common.AuditLogType; import org.ovirt.engine.core.common.action.LockProperties; @@ -26,6 +27,10 @@ super(params); } + public StopGlusterVolumeCommand(GlusterVolumeActionParameters params, CommandContext context) { + super(params, context); + } + @Override protected LockProperties applyLockProperties(LockProperties lockProperties) { return lockProperties.withScope(Scope.Execution).withWait(true); 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 22e98a1..b3f66a2 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 @@ -1677,7 +1677,7 @@ @Override public StatusOnlyReturnForXmlRpc glusterVolumeSnapshotDelete(String volumeName) { JsonRpcRequest request = - new RequestBuilder("GlusterVolume.snapshotDelete").withParameter("volumeName", volumeName) + new RequestBuilder("GlusterVolume.snapshotDeleteAll").withParameter("volumeName", volumeName) .build(); Map<String, Object> response = new FutureMap(this.client, request); return new StatusOnlyReturnForXmlRpc(response); -- To view, visit https://gerrit.ovirt.org/38150 To unsubscribe, visit https://gerrit.ovirt.org/settings Gerrit-MessageType: newchange Gerrit-Change-Id: I0eccbcd4aa3e218ba0d910bd9150bdb0baa2db68 Gerrit-PatchSet: 1 Gerrit-Project: ovirt-engine Gerrit-Branch: master Gerrit-Owner: Shubhendu Tripathi <[email protected]> _______________________________________________ Engine-patches mailing list [email protected] http://lists.ovirt.org/mailman/listinfo/engine-patches
