Martin Peřina has uploaded a new change for review. Change subject: core: Add fencing policy as parameter to fenceNode VDSM verb ......................................................................
core: Add fencing policy as parameter to fenceNode VDSM verb Add fencing policy as a parameter to fenceNode VDSM verb. This policy will be used during VdsNotResponding handling. Currently fencing policy can contain attribute to skip fencing if host has live connection to at least on of its storage domains. If turned on (default in 3.5 clusters) and host has live connection to storage, fencing will be skipped and info is displayed. Change-Id: I61ca142f0630ec2d8c1ec16e44c01af989c19079 Bug-Url: https://bugzilla.redhat.com/1090799 Signed-off-by: Martin Perina <[email protected]> --- M backend/manager/modules/bll/src/main/java/org/ovirt/engine/core/bll/FenceExecutor.java M backend/manager/modules/bll/src/main/java/org/ovirt/engine/core/bll/FenceVdsBaseCommand.java M backend/manager/modules/bll/src/main/java/org/ovirt/engine/core/bll/RestartVdsCommand.java M backend/manager/modules/bll/src/main/java/org/ovirt/engine/core/bll/VdsNotRespondingTreatmentCommand.java M backend/manager/modules/common/src/main/java/org/ovirt/engine/core/common/AuditLogType.java M backend/manager/modules/common/src/main/java/org/ovirt/engine/core/common/action/FenceVdsActionParameters.java M backend/manager/modules/common/src/main/java/org/ovirt/engine/core/common/businessentities/FenceStatusReturnValue.java M backend/manager/modules/common/src/main/java/org/ovirt/engine/core/common/vdscommands/FenceVdsVDSCommandParameters.java M backend/manager/modules/vdsbroker/src/main/java/org/ovirt/engine/core/vdsbroker/jsonrpc/JsonRpcVdsServer.java M backend/manager/modules/vdsbroker/src/main/java/org/ovirt/engine/core/vdsbroker/vdsbroker/FenceStatusReturnForXmlRpc.java M backend/manager/modules/vdsbroker/src/main/java/org/ovirt/engine/core/vdsbroker/vdsbroker/FenceVdsVDSCommand.java M backend/manager/modules/vdsbroker/src/main/java/org/ovirt/engine/core/vdsbroker/vdsbroker/IVdsServer.java M backend/manager/modules/vdsbroker/src/main/java/org/ovirt/engine/core/vdsbroker/vdsbroker/VdsProperties.java M backend/manager/modules/vdsbroker/src/main/java/org/ovirt/engine/core/vdsbroker/vdsbroker/VdsServerConnector.java M backend/manager/modules/vdsbroker/src/main/java/org/ovirt/engine/core/vdsbroker/vdsbroker/VdsServerWrapper.java 15 files changed, 273 insertions(+), 55 deletions(-) git pull ssh://gerrit.ovirt.org:29418/ovirt-engine refs/changes/37/31237/1 diff --git a/backend/manager/modules/bll/src/main/java/org/ovirt/engine/core/bll/FenceExecutor.java b/backend/manager/modules/bll/src/main/java/org/ovirt/engine/core/bll/FenceExecutor.java index 734c412..30afdd9 100644 --- a/backend/manager/modules/bll/src/main/java/org/ovirt/engine/core/bll/FenceExecutor.java +++ b/backend/manager/modules/bll/src/main/java/org/ovirt/engine/core/bll/FenceExecutor.java @@ -8,6 +8,7 @@ import org.ovirt.engine.core.common.businessentities.FenceActionType; import org.ovirt.engine.core.common.businessentities.FenceAgentOrder; import org.ovirt.engine.core.common.businessentities.FenceStatusReturnValue; +import org.ovirt.engine.core.common.businessentities.FencingPolicy; import org.ovirt.engine.core.common.businessentities.NonOperationalReason; import org.ovirt.engine.core.common.businessentities.VDS; import org.ovirt.engine.core.common.businessentities.VDSStatus; @@ -16,11 +17,13 @@ import org.ovirt.engine.core.common.config.Config; import org.ovirt.engine.core.common.config.ConfigValues; import org.ovirt.engine.core.common.errors.VdcBLLException; +import org.ovirt.engine.core.common.utils.FencingPolicyHelper; import org.ovirt.engine.core.common.vdscommands.FenceVdsVDSCommandParameters; import org.ovirt.engine.core.common.vdscommands.SpmStopVDSCommandParameters; import org.ovirt.engine.core.common.vdscommands.VDSCommandType; import org.ovirt.engine.core.common.vdscommands.VDSReturnValue; import org.ovirt.engine.core.compat.Guid; +import org.ovirt.engine.core.compat.Version; import org.ovirt.engine.core.dal.dbbroker.DbFacade; import org.ovirt.engine.core.dal.dbbroker.auditloghandling.AuditLogDirector; import org.ovirt.engine.core.dal.dbbroker.auditloghandling.AuditLogableBase; @@ -38,8 +41,14 @@ private Guid proxyHostId; private String proxyHostName; private Guid skippedProxyHostId=null; + private FencingPolicy fencingPolicy; + private Version minVersionSupportingFencingPol; public FenceExecutor(VDS vds, FenceActionType actionType) { + this(vds, actionType, null); + } + + public FenceExecutor(VDS vds, FenceActionType actionType, FencingPolicy fencingPolicy) { // TODO remove if block after UI patch that should set also cluster & proxy preferences in GetNewVdsFenceStatusParameters if (! vds.getId().equals(Guid.Empty)) { VDS dbVds = DbFacade.getInstance().getVdsDao().get(vds.getId()); @@ -52,6 +61,8 @@ } _vds = vds; _action = actionType; + this.fencingPolicy = fencingPolicy; + minVersionSupportingFencingPol = FencingPolicyHelper.getMinimalSupportedVersion(fencingPolicy); } public boolean findProxyHost() { @@ -210,8 +221,10 @@ String managementOptions = getManagementOptions(order); log.infoFormat("Executing <{0}> Power Management command, Proxy Host:{1}, " - + "Agent:{2}, Target Host:{3}, Management IP:{4}, User:{5}, Options:{6}", actionType, proxyHostName, - managementAgent, _vds.getName(), managementIp, managementUser, managementOptions); + + "Agent:{2}, Target Host:{3}, Management IP:{4}, User:{5}, Options:{6}, Fencing policy:{7}", + actionType, proxyHostName, managementAgent, _vds.getName(), managementIp, managementUser, + managementOptions, + fencingPolicy); return Backend .getInstance() .getResourceManager() @@ -219,7 +232,7 @@ VDSCommandType.FenceVds, new FenceVdsVDSCommandParameters(proxyHostId, _vds.getId(), managementIp, managementPort, managementAgent, managementUser, managementPassword, - managementOptions, actionType)); + managementOptions, actionType, fencingPolicy)); } private String getManagementOptions(FenceAgentOrder order) { @@ -409,6 +422,10 @@ if (StringUtils.isNotEmpty(_vds.getPmSecondaryIp())) { ret = options.isAgentSupported(_vds.getPmSecondaryType()); } + + // check if host supports minimal cluster level needed by fencing policy + ret = ret && _vds.getSupportedClusterVersionsSet().contains(minVersionSupportingFencingPol); + return ret; } }); diff --git a/backend/manager/modules/bll/src/main/java/org/ovirt/engine/core/bll/FenceVdsBaseCommand.java b/backend/manager/modules/bll/src/main/java/org/ovirt/engine/core/bll/FenceVdsBaseCommand.java index 2180d88..09f0329 100644 --- a/backend/manager/modules/bll/src/main/java/org/ovirt/engine/core/bll/FenceVdsBaseCommand.java +++ b/backend/manager/modules/bll/src/main/java/org/ovirt/engine/core/bll/FenceVdsBaseCommand.java @@ -207,11 +207,17 @@ vdsReturnValue = executor.fence(); setFenceSucceeded(vdsReturnValue.getSucceeded()); if (getFenceSucceeded()) { - executor = createFenceExecutor(FenceActionType.Status); - if (waitForStatus(getVds().getName(), getParameters().getAction(), FenceAgentOrder.Primary)) { - handleSpecificCommandActions(); + if (wasSkippedDueToPolicy(vdsReturnValue.getReturnValue())) { + // fencing execution was skipped due to fencing policy + handleFencingSkippedDueToPolicy(vdsReturnValue); + return; } else { - handleWaitFailure(lastStatus, FenceAgentOrder.Primary); + executor = createFenceExecutor(FenceActionType.Status); + if (waitForStatus(getVds().getName(), getParameters().getAction(), FenceAgentOrder.Primary)) { + handleSpecificCommandActions(); + } else { + handleWaitFailure(lastStatus, FenceAgentOrder.Primary); + } } } else { handleError(lastStatus, vdsReturnValue, FenceAgentOrder.Primary); @@ -234,13 +240,19 @@ vdsReturnValue = executor.fence(FenceAgentOrder.Primary); setFenceSucceeded(vdsReturnValue.getSucceeded()); if (getFenceSucceeded()) { - executor = createFenceExecutor(FenceActionType.Status); - if (waitForStatus(getVds().getName(), getParameters().getAction(), FenceAgentOrder.Primary)) { - handleSpecificCommandActions(); + if (wasSkippedDueToPolicy(vdsReturnValue.getReturnValue())) { + // fencing execution was skipped due to fencing policy + handleFencingSkippedDueToPolicy(vdsReturnValue); + return; } else { - // set the executor to perform the action - executor = createFenceExecutor(getParameters().getAction()); - tryOtherSequentialAgent(lastStatus, vdsReturnValue); + executor = createFenceExecutor(FenceActionType.Status); + if (waitForStatus(getVds().getName(), getParameters().getAction(), FenceAgentOrder.Primary)) { + handleSpecificCommandActions(); + } else { + // set the executor to perform the action + executor = createFenceExecutor(getParameters().getAction()); + tryOtherSequentialAgent(lastStatus, vdsReturnValue); + } } } else { tryOtherSequentialAgent(lastStatus, vdsReturnValue); @@ -262,17 +274,22 @@ vdsReturnValue = executor.fence(FenceAgentOrder.Secondary); setFenceSucceeded(vdsReturnValue.getSucceeded()); if (getFenceSucceeded()) { - executor = createFenceExecutor(FenceActionType.Status); - if (waitForStatus(getVds().getName(), getParameters().getAction(), FenceAgentOrder.Secondary)) { - // raise an alert that secondary agent was used - AuditLogableBase logable = new AuditLogableBase(); - logable.setVdsId(getVds().getId()); - logable.addCustomValue("Operation", getParameters().getAction().name()); - AuditLogDirector.log(logable, AuditLogType.VDS_ALERT_SECONDARY_AGENT_USED_FOR_FENCE_OPERATION); - handleSpecificCommandActions(); - } - else { - handleWaitFailure(lastStatus, FenceAgentOrder.Secondary); + if (wasSkippedDueToPolicy(vdsReturnValue.getReturnValue())) { + // fencing execution was skipped due to fencing policy + handleFencingSkippedDueToPolicy(vdsReturnValue); + return; + } else { + executor = createFenceExecutor(FenceActionType.Status); + if (waitForStatus(getVds().getName(), getParameters().getAction(), FenceAgentOrder.Secondary)) { + // raise an alert that secondary agent was used + AuditLogableBase logable = new AuditLogableBase(); + logable.setVdsId(getVds().getId()); + logable.addCustomValue("Operation", getParameters().getAction().name()); + AuditLogDirector.log(logable, AuditLogType.VDS_ALERT_SECONDARY_AGENT_USED_FOR_FENCE_OPERATION); + handleSpecificCommandActions(); + } else { + handleWaitFailure(lastStatus, FenceAgentOrder.Secondary); + } } } else { @@ -342,8 +359,21 @@ secondaryResult = f1.get(); } if (primaryResult.isSucceeded() && secondaryResult.isSucceeded()) { - handleSpecificCommandActions(); - setFenceSucceeded(true); + boolean primarySkipped = wasSkippedDueToPolicy(primaryResult.getValue()); + boolean secondarySkipped = wasSkippedDueToPolicy(secondaryResult.getValue()); + if (primarySkipped && secondarySkipped) { + // fencing execution was skipped due to fencing policy + handleFencingSkippedDueToPolicy(vdsReturnValue); + return; + } else if (primarySkipped || secondarySkipped) { + // fence execution on one agents was skipped and on the other executed + handleError(lastStatus, + primarySkipped ? primaryResult.getValue() : secondaryResult.getValue(), + primarySkipped ? FenceAgentOrder.Primary : FenceAgentOrder.Secondary); + } else { + handleSpecificCommandActions(); + setFenceSucceeded(true); + } } else { handleError(lastStatus, !primaryResult.isSucceeded() ? primaryResult.getValue() : secondaryResult.getValue(), @@ -392,8 +422,11 @@ fenceInvocationResult.setOrder(order); fenceInvocationResult.setValue(fenceExecutor.fence(order)); if (fenceInvocationResult.getValue().getSucceeded()) { - this.executor = createFenceExecutor(FenceActionType.Status); - fenceInvocationResult.setSucceeded(waitForStatus(getVds().getName(), getParameters().getAction(), order)); + if (!wasSkippedDueToPolicy(fenceInvocationResult.getValue().getReturnValue())) { + // execution was not skipped due to policy, get status + this.executor = createFenceExecutor(FenceActionType.Status); + fenceInvocationResult.setSucceeded(waitForStatus(getVds().getName(), getParameters().getAction(), order)); + } } return fenceInvocationResult; } @@ -618,7 +651,25 @@ private FenceExecutor createFenceExecutor(FenceActionType actionType) { return new FenceExecutor( getVds(), - actionType + actionType, + getParameters().getFencingPolicy() ); } + + /** + * Returns {@code true}, if fencing execution was skipped due to fencing policy + */ + protected boolean wasSkippedDueToPolicy(Object returnValue) { + FenceStatusReturnValue fenceResult = null; + if (returnValue instanceof FenceStatusReturnValue) { + fenceResult = (FenceStatusReturnValue) returnValue; + } + return fenceResult != null && fenceResult.getIsSkipped(); + } + + private void handleFencingSkippedDueToPolicy(VDSReturnValue vdsReturnValue) { + setFenceSucceeded(true); + vdsReturnValue.setSucceeded(true); + vdsReturnValue.setReturnValue(FenceStatusReturnValue.SKIPPED); + } } diff --git a/backend/manager/modules/bll/src/main/java/org/ovirt/engine/core/bll/RestartVdsCommand.java b/backend/manager/modules/bll/src/main/java/org/ovirt/engine/core/bll/RestartVdsCommand.java index d1dceb29..2619256 100644 --- a/backend/manager/modules/bll/src/main/java/org/ovirt/engine/core/bll/RestartVdsCommand.java +++ b/backend/manager/modules/bll/src/main/java/org/ovirt/engine/core/bll/RestartVdsCommand.java @@ -4,6 +4,7 @@ import static org.ovirt.engine.core.common.AuditLogType.SYSTEM_VDS_RESTART; import static org.ovirt.engine.core.common.AuditLogType.USER_FAILED_VDS_RESTART; import static org.ovirt.engine.core.common.AuditLogType.USER_VDS_RESTART; +import static org.ovirt.engine.core.common.AuditLogType.VDS_NOT_RESTARTED_DUE_TO_POLICY; import static org.ovirt.engine.core.common.errors.VdcBllMessages.VAR__ACTION__RESTART; import static org.ovirt.engine.core.common.errors.VdcBllMessages.VAR__TYPE__HOST; import static org.ovirt.engine.core.common.errors.VdcBllMessages.VDS_FENCE_OPERATION_FAILED; @@ -44,6 +45,8 @@ @NonTransactiveCommandAttribute public class RestartVdsCommand<T extends FenceVdsActionParameters> extends FenceVdsBaseCommand<T> { + private boolean skippedDueToFencingPolicy; + protected List<VM> getVmList() { return mVmList; } @@ -55,6 +58,7 @@ */ protected RestartVdsCommand(Guid commandId) { super(commandId); + skippedDueToFencingPolicy = false; } public RestartVdsCommand(T parameters) { @@ -63,6 +67,7 @@ public RestartVdsCommand(T parameters, CommandContext commandContext) { super(parameters, commandContext); + skippedDueToFencingPolicy = false; } @@ -89,12 +94,20 @@ returnValueBase = executeVdsFenceAction(vdsId, sessionId, FenceActionType.Stop, VdcActionType.StopVds); } if (returnValueBase.getSucceeded()) { - executeFenceVdsManuallyAction(vdsId, sessionId); + if (wasSkippedDueToPolicy(returnValueBase.getActionReturnValue())) { + // fence execution was skipped due to fencing policy, host should be alive + setSucceeded(true); + setFenceSucceeded(true); + skippedDueToFencingPolicy = true; + return; + } else { + executeFenceVdsManuallyAction(vdsId, sessionId); - // execute StartVds action - returnValueBase = executeVdsFenceAction(vdsId, sessionId, FenceActionType.Start, VdcActionType.StartVds); - setSucceeded(returnValueBase.getSucceeded()); - setFenceSucceeded(getSucceeded()); + // execute StartVds action + returnValueBase = executeVdsFenceAction(vdsId, sessionId, FenceActionType.Start, VdcActionType.StartVds); + setSucceeded(returnValueBase.getSucceeded()); + setFenceSucceeded(getSucceeded()); + } } else { super.handleError(); setSucceeded(false); @@ -126,6 +139,8 @@ FenceVdsActionParameters params = new FenceVdsActionParameters(vdsId, fenceAction); params.setParentCommand(VdcActionType.RestartVds); params.setSessionId(sessionId); + params.setFencingPolicy(getParameters().getFencingPolicy()); + // If Host was in Maintenance, and was restarted manually , it should preserve its status after reboot if (getParameters().getParentCommand() != VdcActionType.VdsNotRespondingTreatment && getVds().getStatus() == VDSStatus.Maintenance) { params.setChangeHostToMaintenanceOnStart(true); @@ -149,7 +164,11 @@ @Override public AuditLogType getAuditLogTypeValue() { if (getSucceeded()) { - return isInternalExecution() ? SYSTEM_VDS_RESTART : USER_VDS_RESTART; + if (skippedDueToFencingPolicy) { + return VDS_NOT_RESTARTED_DUE_TO_POLICY; + } else { + return isInternalExecution() ? SYSTEM_VDS_RESTART : USER_VDS_RESTART; + } } else { return isInternalExecution() ? SYSTEM_FAILED_VDS_RESTART : USER_FAILED_VDS_RESTART; } diff --git a/backend/manager/modules/bll/src/main/java/org/ovirt/engine/core/bll/VdsNotRespondingTreatmentCommand.java b/backend/manager/modules/bll/src/main/java/org/ovirt/engine/core/bll/VdsNotRespondingTreatmentCommand.java index 8b42d2a..f8b7d3e 100644 --- a/backend/manager/modules/bll/src/main/java/org/ovirt/engine/core/bll/VdsNotRespondingTreatmentCommand.java +++ b/backend/manager/modules/bll/src/main/java/org/ovirt/engine/core/bll/VdsNotRespondingTreatmentCommand.java @@ -14,6 +14,7 @@ import org.ovirt.engine.core.common.action.SetStoragePoolStatusParameters; import org.ovirt.engine.core.common.action.VdcActionType; import org.ovirt.engine.core.common.action.VdcReturnValueBase; +import org.ovirt.engine.core.common.businessentities.FencingPolicy; import org.ovirt.engine.core.common.businessentities.StoragePoolStatus; import org.ovirt.engine.core.common.businessentities.VdsSpmStatus; @@ -81,6 +82,12 @@ return; } + // load cluster fencing policy + FencingPolicy fencingPolicy = getDbFacade().getVdsGroupDao().get( + getVds().getVdsGroupId() + ).getFencingPolicy(); + getParameters().setFencingPolicy(fencingPolicy); + // Make sure that the StopVdsCommand that runs by the RestartVds // don't write over our job, and disrupt marking the job status correctly ExecutionContext ec = (ExecutionContext) ObjectUtils.clone(this.getExecutionContext()); diff --git a/backend/manager/modules/common/src/main/java/org/ovirt/engine/core/common/AuditLogType.java b/backend/manager/modules/common/src/main/java/org/ovirt/engine/core/common/AuditLogType.java index 50c848e..ff56c1c 100644 --- a/backend/manager/modules/common/src/main/java/org/ovirt/engine/core/common/AuditLogType.java +++ b/backend/manager/modules/common/src/main/java/org/ovirt/engine/core/common/AuditLogType.java @@ -103,6 +103,7 @@ SYSTEM_VDS_RESTART(121, AuditLogTimeInterval.MINUTE.getValue()), SYSTEM_FAILED_VDS_RESTART(122, AuditLogSeverity.ERROR, AuditLogTimeInterval.MINUTE.getValue()), + VDS_NOT_RESTARTED_DUE_TO_POLICY(618), // Host time drift Alert VDS_TIME_DRIFT_ALERT(604, AuditLogSeverity.WARNING, diff --git a/backend/manager/modules/common/src/main/java/org/ovirt/engine/core/common/action/FenceVdsActionParameters.java b/backend/manager/modules/common/src/main/java/org/ovirt/engine/core/common/action/FenceVdsActionParameters.java index 3b76cb5..e0a5e2e 100644 --- a/backend/manager/modules/common/src/main/java/org/ovirt/engine/core/common/action/FenceVdsActionParameters.java +++ b/backend/manager/modules/common/src/main/java/org/ovirt/engine/core/common/action/FenceVdsActionParameters.java @@ -1,6 +1,7 @@ package org.ovirt.engine.core.common.action; import org.ovirt.engine.core.common.businessentities.FenceActionType; +import org.ovirt.engine.core.common.businessentities.FencingPolicy; import org.ovirt.engine.core.compat.Guid; public class FenceVdsActionParameters extends VdsActionParameters { @@ -16,6 +17,8 @@ private boolean keepPolicyPMEnabled; private FenceActionType action; + + private FencingPolicy fencingPolicy; public FenceVdsActionParameters() { this(null, FenceActionType.Restart); @@ -50,4 +53,12 @@ public void setChangeHostToMaintenanceOnStart(boolean changeHostStatusOnStart) { this.changeHostToMaintenanceOnStart = changeHostStatusOnStart; } + + public FencingPolicy getFencingPolicy() { + return fencingPolicy; + } + + public void setFencingPolicy(FencingPolicy fencingPolicy) { + this.fencingPolicy = fencingPolicy; + } } diff --git a/backend/manager/modules/common/src/main/java/org/ovirt/engine/core/common/businessentities/FenceStatusReturnValue.java b/backend/manager/modules/common/src/main/java/org/ovirt/engine/core/common/businessentities/FenceStatusReturnValue.java index 9982e05..c12d619 100644 --- a/backend/manager/modules/common/src/main/java/org/ovirt/engine/core/common/businessentities/FenceStatusReturnValue.java +++ b/backend/manager/modules/common/src/main/java/org/ovirt/engine/core/common/businessentities/FenceStatusReturnValue.java @@ -8,6 +8,7 @@ private static final long serialVersionUID = 8070963676213797507L; // indicates that operation was skipped because Host is already in requested state. public static final String SKIPPED = "skipped"; + public static final String INITIATED = "initiated"; public FenceStatusReturnValue(String status, String message) { _status = status; _message = message; @@ -30,7 +31,11 @@ } public boolean getIsSkipped() { - return _status.equalsIgnoreCase(SKIPPED); + return SKIPPED.equalsIgnoreCase(_status); + } + + public boolean getIsInitiated() { + return INITIATED.equalsIgnoreCase(_status); } @Override diff --git a/backend/manager/modules/common/src/main/java/org/ovirt/engine/core/common/vdscommands/FenceVdsVDSCommandParameters.java b/backend/manager/modules/common/src/main/java/org/ovirt/engine/core/common/vdscommands/FenceVdsVDSCommandParameters.java index dea35af..cd68c46 100644 --- a/backend/manager/modules/common/src/main/java/org/ovirt/engine/core/common/vdscommands/FenceVdsVDSCommandParameters.java +++ b/backend/manager/modules/common/src/main/java/org/ovirt/engine/core/common/vdscommands/FenceVdsVDSCommandParameters.java @@ -1,11 +1,12 @@ package org.ovirt.engine.core.common.vdscommands; import org.ovirt.engine.core.common.businessentities.FenceActionType; +import org.ovirt.engine.core.common.businessentities.FencingPolicy; import org.ovirt.engine.core.compat.Guid; public class FenceVdsVDSCommandParameters extends VdsIdVDSCommandParametersBase { public FenceVdsVDSCommandParameters(Guid vdsId, Guid targetVdsId, String ip, String port, String type, String user, - String password, String options, FenceActionType action) { + String password, String options, FenceActionType action, FencingPolicy fencingPolicy) { super(vdsId); _targetVdsId = targetVdsId; _ip = ip; @@ -15,6 +16,7 @@ _password = password; _action = action; _options = options; + this.fencingPolicy = fencingPolicy; } private Guid _targetVdsId; @@ -25,6 +27,8 @@ private String _password; private String _options; private FenceActionType _action; + + private FencingPolicy fencingPolicy; public Guid getTargetVdsID() { return _targetVdsId; @@ -63,10 +67,15 @@ _action = FenceActionType.Restart; } + public FencingPolicy getFencingPolicy() { + return fencingPolicy; + } + @Override public String toString() { return String.format("%s, targetVdsId = %s, action = %s, ip = %s, port = %s, type = %s, user = %s, " + - "password = %s, options = '%s'", super.toString(), getTargetVdsID(), getAction(), getIp(), getPort(), - getType(), getUser(), (getPassword() == null ? null : "******"), getOptions()); + "password = %s, options = '%s', policy = '%s'", super.toString(), getTargetVdsID(), getAction(), + getIp(), getPort(), getType(), getUser(), (getPassword() == null ? null : "******"), getOptions(), + getFencingPolicy()); } } 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 1d43c55..6987d63 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 @@ -417,8 +417,9 @@ String password, String action, String secured, - String options) { - JsonRpcRequest request = + String options, + Map<String, Object> fencingPolicy) { + RequestBuilder rb = new RequestBuilder("Host.fenceNode").withParameter("addr", ip) .withParameter("port", port) .withParameter("agent", type) @@ -426,12 +427,14 @@ .withParameter("password", password) .withParameter("action", action) .withOptionalParameter("secure", secured) - .withOptionalParameter("options", options) - .build(); - Map<String, Object> response = - new FutureMap(this.client, request).withResponseKey("power") - .withResponseType(String.class); - return new FenceStatusReturnForXmlRpc(response); + .withOptionalParameter("options", options); + + if (fencingPolicy != null) { + // if fencing policy is null, fence proxy does not support fencing policy parameter + rb.withParameter("fencingPolicy", fencingPolicy); + } + + return new FenceStatusReturnForXmlRpc(new FutureMap(this.client, rb.build())); } @Override diff --git a/backend/manager/modules/vdsbroker/src/main/java/org/ovirt/engine/core/vdsbroker/vdsbroker/FenceStatusReturnForXmlRpc.java b/backend/manager/modules/vdsbroker/src/main/java/org/ovirt/engine/core/vdsbroker/vdsbroker/FenceStatusReturnForXmlRpc.java index a813a12..6aa20e1 100644 --- a/backend/manager/modules/vdsbroker/src/main/java/org/ovirt/engine/core/vdsbroker/vdsbroker/FenceStatusReturnForXmlRpc.java +++ b/backend/manager/modules/vdsbroker/src/main/java/org/ovirt/engine/core/vdsbroker/vdsbroker/FenceStatusReturnForXmlRpc.java @@ -6,11 +6,14 @@ public final class FenceStatusReturnForXmlRpc extends StatusReturnForXmlRpc { private static final String POWER = "power"; + private static final String OPERATION_STATUS = "operationStatus"; // [XmlRpcMissingMapping(MappingAction.Ignore), XmlRpcMember("power")] public String power; + public String operationStatus; public FenceStatusReturnForXmlRpc(Map<String, Object> innerMap) { super(innerMap); power = (String) innerMap.get(POWER); + operationStatus = (String) innerMap.get(OPERATION_STATUS); } } diff --git a/backend/manager/modules/vdsbroker/src/main/java/org/ovirt/engine/core/vdsbroker/vdsbroker/FenceVdsVDSCommand.java b/backend/manager/modules/vdsbroker/src/main/java/org/ovirt/engine/core/vdsbroker/vdsbroker/FenceVdsVDSCommand.java index e3f2786..543986f 100644 --- a/backend/manager/modules/vdsbroker/src/main/java/org/ovirt/engine/core/vdsbroker/vdsbroker/FenceVdsVDSCommand.java +++ b/backend/manager/modules/vdsbroker/src/main/java/org/ovirt/engine/core/vdsbroker/vdsbroker/FenceVdsVDSCommand.java @@ -1,9 +1,16 @@ package org.ovirt.engine.core.vdsbroker.vdsbroker; +import java.util.HashMap; +import java.util.Map; + import org.ovirt.engine.core.common.AuditLogType; import org.ovirt.engine.core.common.businessentities.FenceActionType; import org.ovirt.engine.core.common.businessentities.FenceStatusReturnValue; +import org.ovirt.engine.core.common.businessentities.StorageDomain; +import org.ovirt.engine.core.common.businessentities.StorageDomainType; import org.ovirt.engine.core.common.businessentities.VDS; +import org.ovirt.engine.core.common.businessentities.vds_spm_id_map; +import org.ovirt.engine.core.common.utils.FencingPolicyHelper; import org.ovirt.engine.core.common.vdscommands.FenceVdsVDSCommandParameters; import org.ovirt.engine.core.compat.Guid; import org.ovirt.engine.core.dal.dbbroker.DbFacade; @@ -15,8 +22,32 @@ public class FenceVdsVDSCommand<P extends FenceVdsVDSCommandParameters> extends VdsBrokerCommand<P> { private FenceStatusReturnForXmlRpc _result; + /** + * VDS which acts as fence proxy + */ + private VDS proxyVds; + + /** + * VDS which should be fenced + */ + private VDS targetVds; + public FenceVdsVDSCommand(P parameters) { super(parameters); + } + + private VDS getProxyVds() { + if (proxyVds == null) { + proxyVds = DbFacade.getInstance().getVdsDao().get(getParameters().getVdsId()); + } + return proxyVds; + } + + private VDS getTargetVds() { + if (targetVds == null) { + targetVds = DbFacade.getInstance().getVdsDao().get(getParameters().getTargetVdsID()); + } + return targetVds; } /** @@ -47,15 +78,18 @@ @Override protected void executeVdsBrokerCommand() { // We have to pass here the proxy host cluster compatibility version - VDS vds = getDbFacade().getVdsDao().get(getParameters().getVdsId()); + VDS vds = getProxyVds(); VdsFenceOptions vdsFencingOptions = new VdsFenceOptions(getParameters().getType(), getParameters().getOptions(), vds.getVdsGroupCompatibilityVersion().toString()); String options = vdsFencingOptions.ToInternalString(); + // ignore starting already started host or stopping already stopped host. if (!isAlreadyInRequestedStatus(options)) { _result = getBroker().fenceNode(getParameters().getIp(), "", getParameters().getType(), getParameters().getUser(), - getParameters().getPassword(), getActualActionName(), "", options); + getParameters().getPassword(), getActualActionName(), "", options, + convertFencingPolicy() + ); proceedProxyReturnValue(); getVDSReturnValue().setSucceeded(false); @@ -73,7 +107,11 @@ FenceStatusReturnValue fenceStatusReturnValue = new FenceStatusReturnValue(stat, msg); setReturnValue(fenceStatusReturnValue); } else { - setReturnValue((_result.mStatus.mMessage != null) ? _result.mStatus.mMessage : ""); + FenceStatusReturnValue fenceStatusReturnValue = new FenceStatusReturnValue( + _result.operationStatus, + _result.mStatus.mMessage != null ? _result.mStatus.mMessage : "" + ); + setReturnValue(fenceStatusReturnValue); getVDSReturnValue().setSucceeded(true); } } else { @@ -111,7 +149,9 @@ FenceActionType action = getParameters().getAction(); _result = getBroker().fenceNode(getParameters().getIp(), "", getParameters().getType(), getParameters().getUser(), - getParameters().getPassword(), "status", "", options); + getParameters().getPassword(), "status", "", options, + null + ); if (_result.power != null) { String powerStatus = _result.power.toLowerCase(); if ((action == FenceActionType.Start && powerStatus.equals("on")) || @@ -121,6 +161,44 @@ return ret; } + private Map<String, Object> convertFencingPolicy() { + Map<String, Object> map = null; + if (getParameters().getFencingPolicy() != null && + FencingPolicyHelper.isFencingPolicySupported(getProxyVds().getSupportedClusterVersionsSet())) { + // fencing policy is entered and proxy supports passing fencing policy parameters + map = new HashMap<>(); + if (getParameters().getFencingPolicy().isSkipFencingIfSDActive()) { + // create map STORAGE_DOMAIN_GUID -> HOST_SPM_ID to pass to fence proxy + map.put(VdsProperties.STORAGE_DOMAIN_HOST_ID_MAP, createStorageDomainHostIdMap()); + } + } + return map; + } + + private Map<Guid, Integer> createStorageDomainHostIdMap() { + Map<Guid, Integer> map = null; + if (getParameters().getFencingPolicy().isSkipFencingIfSDActive()) { + map = new HashMap<>(); + DbFacade dbf = DbFacade.getInstance(); + + vds_spm_id_map hostIdRecord = dbf.getVdsSpmIdMapDao().get( + getTargetVds().getId() + ); + + // create a map SD_GUID -> HOST_ID + for (StorageDomain sd : dbf.getStorageDomainDao().getAllForStoragePool( + getTargetVds().getStoragePoolId()) + ) { + if (sd.getStorageStaticData().getStorageDomainType() == StorageDomainType.Master || + sd.getStorageStaticData().getStorageDomainType() == StorageDomainType.Data) { + // VDS_SPM_ID identifies the host in sanlock + map.put(sd.getId(), hostIdRecord.getvds_spm_id()); + } + } + } + return map; + } + @Override protected StatusForXmlRpc getReturnStatus() { return (_result.mStatus != null) ? _result.mStatus : new StatusForXmlRpc(); 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 eb92bff..4d3f8cf 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 @@ -94,7 +94,7 @@ StatusOnlyReturnForXmlRpc setSafeNetworkConfig(); FenceStatusReturnForXmlRpc fenceNode(String ip, String port, String type, String user, String password, - String action, String secured, String options); + String action, String secured, String options, Map<String, Object> fencingPolicy); ServerConnectionStatusReturnForXmlRpc connectStorageServer(int serverType, String spUUID, Map<String, String>[] args); diff --git a/backend/manager/modules/vdsbroker/src/main/java/org/ovirt/engine/core/vdsbroker/vdsbroker/VdsProperties.java b/backend/manager/modules/vdsbroker/src/main/java/org/ovirt/engine/core/vdsbroker/vdsbroker/VdsProperties.java index 0f7f7f1..0e9129c 100644 --- a/backend/manager/modules/vdsbroker/src/main/java/org/ovirt/engine/core/vdsbroker/vdsbroker/VdsProperties.java +++ b/backend/manager/modules/vdsbroker/src/main/java/org/ovirt/engine/core/vdsbroker/vdsbroker/VdsProperties.java @@ -365,6 +365,10 @@ public static final String QOS_PEAK = "peak"; public static final String QOS_BURST = "burst"; + // fencing policy parameters + public static final String STORAGE_DOMAIN_HOST_ID_MAP = "storageDomainHostIdMap"; + + public static String migrationMethodtoString(MigrationMethod method) { switch (method) { case OFFLINE: diff --git a/backend/manager/modules/vdsbroker/src/main/java/org/ovirt/engine/core/vdsbroker/vdsbroker/VdsServerConnector.java b/backend/manager/modules/vdsbroker/src/main/java/org/ovirt/engine/core/vdsbroker/vdsbroker/VdsServerConnector.java index 57ddf0f..69c1ae7 100644 --- a/backend/manager/modules/vdsbroker/src/main/java/org/ovirt/engine/core/vdsbroker/vdsbroker/VdsServerConnector.java +++ b/backend/manager/modules/vdsbroker/src/main/java/org/ovirt/engine/core/vdsbroker/vdsbroker/VdsServerConnector.java @@ -78,6 +78,9 @@ public Map<String, Object> fenceNode(String ip, String port, String type, String user, String password, String action, String secured, String options); + public Map<String, Object> fenceNode(String ip, String port, String type, String user, String password, + String action, String secured, String options, Map<String, Object> fencingPolicy); + public Map<String, Object> connectStorageServer(int serverType, String spUUID, Map<String, String>[] args); public Map<String, Object> disconnectStorageServer(int serverType, String spUUID, Map<String, String>[] args); diff --git a/backend/manager/modules/vdsbroker/src/main/java/org/ovirt/engine/core/vdsbroker/vdsbroker/VdsServerWrapper.java b/backend/manager/modules/vdsbroker/src/main/java/org/ovirt/engine/core/vdsbroker/vdsbroker/VdsServerWrapper.java index 395bc02..02ec14f 100644 --- a/backend/manager/modules/vdsbroker/src/main/java/org/ovirt/engine/core/vdsbroker/vdsbroker/VdsServerWrapper.java +++ b/backend/manager/modules/vdsbroker/src/main/java/org/ovirt/engine/core/vdsbroker/vdsbroker/VdsServerWrapper.java @@ -400,10 +400,17 @@ @Override public FenceStatusReturnForXmlRpc fenceNode(String ip, String port, String type, String user, String password, - String action, String secured, String options) { + String action, String secured, String options, Map<String, Object> fencingPolicy) { try { - Map<String, Object> xmlRpcReturnValue = vdsServer.fenceNode(ip, port, type, user, password, action, - secured, options); + Map<String, Object> xmlRpcReturnValue; + if (fencingPolicy == null) { + // if fencing policy is null, fence proxy does not support fencing policy parameter + xmlRpcReturnValue = vdsServer.fenceNode(ip, port, type, user, password, action, + secured, options); + } else { + xmlRpcReturnValue = vdsServer.fenceNode(ip, port, type, user, password, action, + secured, options, fencingPolicy); + } FenceStatusReturnForXmlRpc wrapper = new FenceStatusReturnForXmlRpc(xmlRpcReturnValue); return wrapper; } catch (UndeclaredThrowableException ute) { -- To view, visit http://gerrit.ovirt.org/31237 To unsubscribe, visit http://gerrit.ovirt.org/settings Gerrit-MessageType: newchange Gerrit-Change-Id: I61ca142f0630ec2d8c1ec16e44c01af989c19079 Gerrit-PatchSet: 1 Gerrit-Project: ovirt-engine Gerrit-Branch: ovirt-engine-3.5 Gerrit-Owner: Martin Peřina <[email protected]> _______________________________________________ Engine-patches mailing list [email protected] http://lists.ovirt.org/mailman/listinfo/engine-patches
