Michael Kublin has uploaded a new change for review. Change subject: engine: We are not blocking reconstruct on domains during spm recontend (#843100) ......................................................................
engine: We are not blocking reconstruct on domains during spm recontend (#843100) https://bugzilla.redhat.com/843100 The problem was caused by race which was created by simentenious run of maintaince master storage domain and spm host. In order to solve a problem a locks will be used. A shared lock on pool will be use at MaintananceNumberOfVdssCommand if we are trying to maintaince spm. An exclusive lock will be used in DeactivateStorageDomainCommand if we are trying to deactivate master domain and shared lock on any other data domains. The patch contains a fix of possible NullPointerException at DeactivateStorageDomainCommand Change of order moving to maintaince of hosts at MaintananceNumberOfVdssCommand, in order to move spm a last to maintaince. Change-Id: Ia929d8cfab5904cb8e66d18cf50e037d36d8d373 Signed-off-by: Michael Kublin <mkub...@redhat.com> --- M backend/manager/modules/bll/src/main/java/org/ovirt/engine/core/bll/MaintananceNumberOfVdssCommand.java M backend/manager/modules/bll/src/main/java/org/ovirt/engine/core/bll/MaintananceVdsCommand.java M backend/manager/modules/bll/src/main/java/org/ovirt/engine/core/bll/storage/DeactivateStorageDomainCommand.java M backend/manager/modules/dal/src/main/java/org/ovirt/engine/core/dal/VdcBllMessages.java M backend/manager/modules/dal/src/main/resources/bundles/AppErrors.properties M frontend/webadmin/modules/frontend/src/main/java/org/ovirt/engine/ui/frontend/AppErrors.java M frontend/webadmin/modules/userportal-gwtp/src/main/resources/org/ovirt/engine/ui/frontend/AppErrors.properties M frontend/webadmin/modules/webadmin/src/main/resources/org/ovirt/engine/ui/frontend/AppErrors.properties 8 files changed, 255 insertions(+), 188 deletions(-) git pull ssh://gerrit.ovirt.org:29418/ovirt-engine refs/changes/72/7172/1 diff --git a/backend/manager/modules/bll/src/main/java/org/ovirt/engine/core/bll/MaintananceNumberOfVdssCommand.java b/backend/manager/modules/bll/src/main/java/org/ovirt/engine/core/bll/MaintananceNumberOfVdssCommand.java index 7b1c886..8f5c5dd 100644 --- a/backend/manager/modules/bll/src/main/java/org/ovirt/engine/core/bll/MaintananceNumberOfVdssCommand.java +++ b/backend/manager/modules/bll/src/main/java/org/ovirt/engine/core/bll/MaintananceNumberOfVdssCommand.java @@ -5,6 +5,7 @@ import java.util.HashMap; import java.util.HashSet; import java.util.List; +import java.util.Map; import java.util.Set; import org.apache.commons.lang.StringUtils; @@ -25,23 +26,22 @@ import org.ovirt.engine.core.common.businessentities.Network; import org.ovirt.engine.core.common.errors.VdcBLLException; import org.ovirt.engine.core.common.errors.VdcBllErrors; +import org.ovirt.engine.core.common.locks.LockingGroup; import org.ovirt.engine.core.common.vdscommands.SetVdsStatusVDSCommandParameters; import org.ovirt.engine.core.common.vdscommands.VDSCommandType; import org.ovirt.engine.core.common.vdscommands.VdsIdVDSCommandParametersBase; import org.ovirt.engine.core.compat.Guid; import org.ovirt.engine.core.dal.VdcBllMessages; import org.ovirt.engine.core.dal.dbbroker.DbFacade; -import org.ovirt.engine.core.utils.log.Log; -import org.ovirt.engine.core.utils.log.LogFactory; @InternalCommandAttribute @NonTransactiveCommandAttribute public class MaintananceNumberOfVdssCommand<T extends MaintananceNumberOfVdssParameters> extends CommandBase<T> { private static final long serialVersionUID = -5691756067222085075L; - private static Log log = LogFactory.getLog(MaintananceNumberOfVdssCommand.class); private final HashMap<Guid, VDS> vdssToMaintenance = new HashMap<Guid, VDS>(); private ArrayList<Guid> _vdsGroupIds; private final List<PermissionSubject> inspectedEntitiesMap; + private Map<String, String> sharedLockMap; public MaintananceNumberOfVdssCommand(T parameters) { super(parameters); @@ -55,15 +55,25 @@ } private void MoveVdssToGoingToMaintananceMode() { + List<VDS> spms = new ArrayList<VDS>(); for (VDS vds : vdssToMaintenance.values()) { - if (vds.getstatus() != VDSStatus.PreparingForMaintenance && vds.getstatus() != VDSStatus.NonResponsive - && vds.getstatus() != VDSStatus.Down) { - Backend.getInstance() - .getResourceManager() - .RunVdsCommand( - VDSCommandType.SetVdsStatus, - new SetVdsStatusVDSCommandParameters(vds.getId(), VDSStatus.PreparingForMaintenance)); + if (vds.getspm_status() != VdsSpmStatus.SPM) { + setVdsStatusToPrepareForMaintaice(vds); + } else { + spms.add(vds); } + } + for (VDS vds : spms) { + setVdsStatusToPrepareForMaintaice(vds); + } + freeLock(); + } + + private void setVdsStatusToPrepareForMaintaice(VDS vds) { + if (vds.getstatus() != VDSStatus.PreparingForMaintenance && vds.getstatus() != VDSStatus.NonResponsive + && vds.getstatus() != VDSStatus.Down) { + runVdsCommand(VDSCommandType.SetVdsStatus, + new SetVdsStatusVDSCommandParameters(vds.getId(), VDSStatus.PreparingForMaintenance)); } } @@ -81,6 +91,12 @@ getReturnValue().setCanDoAction(false); } } + } + + @Override + protected void setActionMessageParameters() { + addCanDoActionMessage(VdcBllMessages.VAR__TYPE__HOST); + addCanDoActionMessage(VdcBllMessages.VAR__ACTION__MAINTENANCE); } @Override @@ -106,136 +122,154 @@ List<String> hostsWithNonMigratableVms = new ArrayList<String>(); List<String> nonMigratableVms = new ArrayList<String>(); - // check if one of the target vdss is spm, if so check that there are no - // tasks running for (Guid vdsId : getParameters().getVdsIdList()) { VDS vds = DbFacade.getInstance().getVdsDAO().get(vdsId); if (vds == null) { log.error(String.format("ResourceManager::vdsMaintenance could not find vds_id = '%1$s'", vdsId)); addCanDoActionMessage(VdcBllMessages.VDS_INVALID_SERVER_ID); result = false; - } else { - List<VM> vms = getVmDAO().getAllRunningForVds(vdsId); - if (vms.size() > 0) { - vdsWithRunningVMs.add(vdsId); - } - _vdsGroupIds.add(vds.getvds_group_id()); - List<String> nonMigratableVmDescriptionsToFrontEnd = new ArrayList<String>(); - for (VM vm : vms) { - if (vm.getMigrationSupport() != MigrationSupport.MIGRATABLE) { - nonMigratableVmDescriptionsToFrontEnd.add(vm.getvm_name()); - } - } - - if (nonMigratableVmDescriptionsToFrontEnd.size() > 0) { - hostsWithNonMigratableVms.add(vds.getvds_name()); - nonMigratableVms.addAll(nonMigratableVmDescriptionsToFrontEnd); - - // The non migratable VM names will be comma separated - log.error(String.format("VDS %1$s contains non migratable VMs", vdsId)); - result = false; - - } else if (vds.getstatus() == VDSStatus.Maintenance) { - addCanDoActionMessage(VdcBllMessages.VDS_CANNOT_MAINTENANCE_VDS_IS_IN_MAINTENANCE); - result = false; - } else if (vds.getspm_status() == VdsSpmStatus.Contending) { - addCanDoActionMessage(VdcBllMessages.VDS_CANNOT_MAINTENANCE_SPM_CONTENDING); - result = false; - } else if (vds.getstatus() == VDSStatus.NonResponsive && vds.getvm_count() > 0) { - result = false; - hostNotRespondingList.add(vds.getvds_name()); - } else if (vds.getstatus() == VDSStatus.NonResponsive && vds.getspm_status() != VdsSpmStatus.None) { - result = false; - addCanDoActionMessage(VdcBllMessages.VDS_CANNOT_MAINTENANCE_VDS_IS_NOT_RESPONDING_AND_SPM); - } else if (vds.getspm_status() == VdsSpmStatus.SPM && vds.getstatus() == VDSStatus.Up) { - try { - @SuppressWarnings("unchecked") - HashMap<Guid, AsyncTaskStatus> taskStatuses = - (HashMap<Guid, AsyncTaskStatus>) Backend - .getInstance() - .getResourceManager() - .RunVdsCommand(VDSCommandType.HSMGetAllTasksStatuses, - new VdsIdVDSCommandParametersBase(vdsId)).getReturnValue(); - if (taskStatuses.size() > 0) { - addCanDoActionMessage(VdcBllMessages.VDS_CANNOT_MAINTENANCE_SPM_WITH_RUNNING_TASKS); - result = false; - } - } catch (VdcBLLException e) { - if (e.getErrorCode() == VdcBllErrors.VDS_NETWORK_ERROR) { - addCanDoActionMessage(VdcBllMessages.VDS_CANNOT_MAINTENANCE_VDS_IS_NOT_RESPONDING_AND_SPM); - result = false; - } else { - log.error("Error getting spm task list.", e); - } - } catch (RuntimeException exp) { - log.error("Error getting spm task list.", exp); - } - } - if (!vdssToMaintenance.containsKey(vdsId)) { - vdssToMaintenance.put(vdsId, vds); + continue; + } + if (!vdssToMaintenance.containsKey(vdsId)) { + vdssToMaintenance.put(vdsId, vds); + if (vds.getspm_status() == VdsSpmStatus.SPM) { + addSharedLockEntry(vds); } } } - - // If one of the host is non responsive with running VM's, add a CanDoAction message. - handleNonResponsiveHosts(hostNotRespondingList); - - // If one of the vms is non migratable, add a CanDoAction message. - handleNonMigratableVms(hostsWithNonMigratableVms, nonMigratableVms); - + result = acquireLockInternal(); if (result) { - // Remove all redundant clusters in clusters list, by adding it to a - // set. - // For each cluster check for each host that belongs to it, if its a - // part of the parameters and - // if there are running hosts for it - if it is up and is not in the - // parameters -migration will be possible - // to be performed, and there is no point to continue the check for - // the given cluster - otherwise, - // if the host is up and in the parameters - it may be that the - // cluster is problematic (no hosts in up - // state that we will be able to migrate VMs to) - - // In the end - if the clusters list is not empty - this is an - // error, use the "problematic clusters list" to format an error to - // the client - Set<Guid> clustersAsSet = new HashSet<Guid>(); - clustersAsSet.addAll(_vdsGroupIds); - List<String> problematicClusters = new ArrayList<String>(); - List<String> allHostsWithRunningVms = new ArrayList<String>(); - for (Guid clusterID : clustersAsSet) { - List<VDS> vdsList = DbFacade.getInstance().getVdsDAO().getAllForVdsGroup(clusterID); - boolean vdsForMigrationExists = - checkIfThereIsVDSToHoldMigratedVMs(getParameters().getVdsIdList(), vdsList); - - if (!vdsForMigrationExists) { - List<String> candidateHostsWithRunningVms = new ArrayList<String>(); - for (VDS vdsInCluster : vdsList) { - if (vdsWithRunningVMs.contains(vdsInCluster.getId())) { - candidateHostsWithRunningVms.add(vdsInCluster.getvds_name()); + // check if one of the target vdss is spm, if so check that there are no + // tasks running + for (Guid vdsId : getParameters().getVdsIdList()) { + VDS vds = vdssToMaintenance.get(vdsId); + if (vds != null) { + List<VM> vms = getVmDAO().getAllRunningForVds(vdsId); + if (vms.size() > 0) { + vdsWithRunningVMs.add(vdsId); + } + _vdsGroupIds.add(vds.getvds_group_id()); + List<String> nonMigratableVmDescriptionsToFrontEnd = new ArrayList<String>(); + for (VM vm : vms) { + if (vm.getMigrationSupport() != MigrationSupport.MIGRATABLE) { + nonMigratableVmDescriptionsToFrontEnd.add(vm.getvm_name()); } } - // Passed on all vds in cluster - if map is not empty (host found with VMs) - - // this is indeed a problematic - // cluster - if (!candidateHostsWithRunningVms.isEmpty()) { - addClusterDetails(clusterID, problematicClusters); - allHostsWithRunningVms.addAll(candidateHostsWithRunningVms); + + if (nonMigratableVmDescriptionsToFrontEnd.size() > 0) { + hostsWithNonMigratableVms.add(vds.getvds_name()); + nonMigratableVms.addAll(nonMigratableVmDescriptionsToFrontEnd); + + // The non migratable VM names will be comma separated + log.error(String.format("VDS %1$s contains non migratable VMs", vdsId)); + result = false; + + } else if (vds.getstatus() == VDSStatus.Maintenance) { + addCanDoActionMessage(VdcBllMessages.VDS_CANNOT_MAINTENANCE_VDS_IS_IN_MAINTENANCE); + result = false; + } else if (vds.getspm_status() == VdsSpmStatus.Contending) { + addCanDoActionMessage(VdcBllMessages.VDS_CANNOT_MAINTENANCE_SPM_CONTENDING); + result = false; + } else if (vds.getstatus() == VDSStatus.NonResponsive && vds.getvm_count() > 0) { + result = false; + hostNotRespondingList.add(vds.getvds_name()); + } else if (vds.getstatus() == VDSStatus.NonResponsive && vds.getspm_status() != VdsSpmStatus.None) { + result = false; + addCanDoActionMessage(VdcBllMessages.VDS_CANNOT_MAINTENANCE_VDS_IS_NOT_RESPONDING_AND_SPM); + } else if (vds.getspm_status() == VdsSpmStatus.SPM && vds.getstatus() == VDSStatus.Up) { + try { + @SuppressWarnings("unchecked") + HashMap<Guid, AsyncTaskStatus> taskStatuses = + (HashMap<Guid, AsyncTaskStatus>) Backend + .getInstance() + .getResourceManager() + .RunVdsCommand(VDSCommandType.HSMGetAllTasksStatuses, + new VdsIdVDSCommandParametersBase(vdsId)).getReturnValue(); + if (taskStatuses.size() > 0) { + addCanDoActionMessage(VdcBllMessages.VDS_CANNOT_MAINTENANCE_SPM_WITH_RUNNING_TASKS); + result = false; + } + } catch (VdcBLLException e) { + if (e.getErrorCode() == VdcBllErrors.VDS_NETWORK_ERROR) { + addCanDoActionMessage(VdcBllMessages.VDS_CANNOT_MAINTENANCE_VDS_IS_NOT_RESPONDING_AND_SPM); + result = false; + } else { + log.error("Error getting spm task list.", e); + } + } catch (RuntimeException exp) { + log.error("Error getting spm task list.", exp); + } } } } - // If there are problematic clusters - result = problematicClusters.isEmpty(); - if (!result) { - addCanDoActionMessage(VdcBllMessages.CANNOT_MAINTANANCE_VDS_RUN_VMS_NO_OTHER_RUNNING_VDS); - String commaDelimitedClusters = StringUtils.join(problematicClusters, ","); - getReturnValue().getCanDoActionMessages().add(String.format("$ClustersList %1$s", - commaDelimitedClusters)); - getReturnValue().getCanDoActionMessages().add(String.format("$HostsList %1$s", - StringUtils.join(allHostsWithRunningVms, ","))); + + // If one of the host is non responsive with running VM's, add a CanDoAction message. + handleNonResponsiveHosts(hostNotRespondingList); + + // If one of the vms is non migratable, add a CanDoAction message. + handleNonMigratableVms(hostsWithNonMigratableVms, nonMigratableVms); + + if (result) { + // Remove all redundant clusters in clusters list, by adding it to a + // set. + // For each cluster check for each host that belongs to it, if its a + // part of the parameters and + // if there are running hosts for it - if it is up and is not in the + // parameters -migration will be possible + // to be performed, and there is no point to continue the check for + // the given cluster - otherwise, + // if the host is up and in the parameters - it may be that the + // cluster is problematic (no hosts in up + // state that we will be able to migrate VMs to) + + // In the end - if the clusters list is not empty - this is an + // error, use the "problematic clusters list" to format an error to + // the client + Set<Guid> clustersAsSet = new HashSet<Guid>(); + clustersAsSet.addAll(_vdsGroupIds); + List<String> problematicClusters = new ArrayList<String>(); + List<String> allHostsWithRunningVms = new ArrayList<String>(); + for (Guid clusterID : clustersAsSet) { + List<VDS> vdsList = DbFacade.getInstance().getVdsDAO().getAllForVdsGroup(clusterID); + boolean vdsForMigrationExists = + checkIfThereIsVDSToHoldMigratedVMs(getParameters().getVdsIdList(), vdsList); + + if (!vdsForMigrationExists) { + List<String> candidateHostsWithRunningVms = new ArrayList<String>(); + for (VDS vdsInCluster : vdsList) { + if (vdsWithRunningVMs.contains(vdsInCluster.getId())) { + candidateHostsWithRunningVms.add(vdsInCluster.getvds_name()); + } + } + // Passed on all vds in cluster - if map is not empty (host found with VMs) - + // this is indeed a problematic + // cluster + if (!candidateHostsWithRunningVms.isEmpty()) { + addClusterDetails(clusterID, problematicClusters); + allHostsWithRunningVms.addAll(candidateHostsWithRunningVms); + } + } + } + // If there are problematic clusters + result = problematicClusters.isEmpty(); + if (!result) { + addCanDoActionMessage(VdcBllMessages.CANNOT_MAINTANANCE_VDS_RUN_VMS_NO_OTHER_RUNNING_VDS); + String commaDelimitedClusters = StringUtils.join(problematicClusters, ","); + getReturnValue().getCanDoActionMessages().add(String.format("$ClustersList %1$s", + commaDelimitedClusters)); + getReturnValue().getCanDoActionMessages().add(String.format("$HostsList %1$s", + StringUtils.join(allHostsWithRunningVms, ","))); + } } } return result; + } + + private void addSharedLockEntry(VDS vds) { + if (sharedLockMap == null) { + sharedLockMap = new HashMap<String, String>(); + } + sharedLockMap.put(vds.getstorage_pool_id().toString(), LockingGroup.POOL.name()); } /** @@ -299,6 +333,11 @@ } @Override + protected Map<String, String> getSharedLocks() { + return sharedLockMap; + } + + @Override public List<PermissionSubject> getPermissionCheckSubjects() { return Collections.unmodifiableList(inspectedEntitiesMap); } diff --git a/backend/manager/modules/bll/src/main/java/org/ovirt/engine/core/bll/MaintananceVdsCommand.java b/backend/manager/modules/bll/src/main/java/org/ovirt/engine/core/bll/MaintananceVdsCommand.java index d3d635d..6d8e707 100644 --- a/backend/manager/modules/bll/src/main/java/org/ovirt/engine/core/bll/MaintananceVdsCommand.java +++ b/backend/manager/modules/bll/src/main/java/org/ovirt/engine/core/bll/MaintananceVdsCommand.java @@ -32,14 +32,11 @@ import org.ovirt.engine.core.dal.VdcBllMessages; import org.ovirt.engine.core.dal.dbbroker.DbFacade; import org.ovirt.engine.core.dal.job.ExecutionMessageDirector; -import org.ovirt.engine.core.utils.log.Log; -import org.ovirt.engine.core.utils.log.LogFactory; import org.ovirt.engine.core.vdsbroker.irsbroker.IrsBrokerCommand; public class MaintananceVdsCommand<T extends MaintananceVdsParameters> extends VdsCommand<T> { private static final long serialVersionUID = -7604781532599945079L; - private static Log log = LogFactory.getLog(MaintananceVdsCommand.class); private final boolean _isInternal; private List<VM> vms; @@ -196,5 +193,4 @@ Backend.getInstance().runInternalAction(VdcActionType.DisconnectHostFromStoragePoolServers, tempVar); } } - } diff --git a/backend/manager/modules/bll/src/main/java/org/ovirt/engine/core/bll/storage/DeactivateStorageDomainCommand.java b/backend/manager/modules/bll/src/main/java/org/ovirt/engine/core/bll/storage/DeactivateStorageDomainCommand.java index 852e433..e57bed1 100644 --- a/backend/manager/modules/bll/src/main/java/org/ovirt/engine/core/bll/storage/DeactivateStorageDomainCommand.java +++ b/backend/manager/modules/bll/src/main/java/org/ovirt/engine/core/bll/storage/DeactivateStorageDomainCommand.java @@ -1,7 +1,11 @@ package org.ovirt.engine.core.bll.storage; +import java.util.Collections; +import java.util.HashMap; import java.util.List; +import java.util.Map; +import org.ovirt.engine.core.bll.LockIdNameAttribute; import org.ovirt.engine.core.bll.NonTransactiveCommandAttribute; import org.ovirt.engine.core.common.AuditLogType; import org.ovirt.engine.core.common.action.StorageDomainPoolParametersBase; @@ -12,6 +16,7 @@ import org.ovirt.engine.core.common.businessentities.VDS; import org.ovirt.engine.core.common.businessentities.storage_domains; import org.ovirt.engine.core.common.businessentities.storage_pool_iso_map; +import org.ovirt.engine.core.common.locks.LockingGroup; import org.ovirt.engine.core.common.vdscommands.DeactivateStorageDomainVDSCommandParameters; import org.ovirt.engine.core.common.vdscommands.DisconnectStoragePoolVDSCommandParameters; import org.ovirt.engine.core.common.vdscommands.IrsBaseVDSCommandParameters; @@ -25,11 +30,14 @@ import org.ovirt.engine.core.utils.linq.Predicate; import org.ovirt.engine.core.utils.transaction.TransactionMethod; +@LockIdNameAttribute @NonTransactiveCommandAttribute(forceCompensation = true) public class DeactivateStorageDomainCommand<T extends StorageDomainPoolParametersBase> extends StorageDomainCommandBase<T> { protected Guid _newMasterStorageDomainId = Guid.Empty; private storage_domains _newMaster; + protected boolean _isLastMaster; + private VDS spm; protected storage_domains getNewMaster(boolean duringReconstruct) { if (_newMaster == null && Guid.Empty.equals(_newMasterStorageDomainId)) { @@ -43,9 +51,6 @@ protected void setNewMaster(storage_domains value) { _newMaster = value; } - - protected boolean _isLastMaster; - private VDS spm; public DeactivateStorageDomainCommand(T parameters) { super(parameters); @@ -62,9 +67,13 @@ } @Override - protected boolean canDoAction() { - super.canDoAction(); + protected void setActionMessageParameters() { + addCanDoActionMessage(VdcBllMessages.VAR__TYPE__STORAGE__DOMAIN); addCanDoActionMessage(VdcBllMessages.VAR__ACTION__DEACTIVATE); + } + + @Override + protected boolean canDoAction() { if (!(CheckStorageDomain() && checkStorageDomainStatus(StorageDomainStatus.Active))) { return false; } @@ -166,64 +175,55 @@ getStorageDomain().getStorageDynamicData().setavailable_disk_size(null); getStorageDomain().getStorageDynamicData().setused_disk_size(null); } - boolean succeeded = getBackend().getResourceManager() - .RunVdsCommand( - VDSCommandType.DeactivateStorageDomain, - new DeactivateStorageDomainVDSCommandParameters(getStoragePool().getId(), - getStorageDomain() - .getId(), - _newMasterStorageDomainId, - getStoragePool().getmaster_domain_version())) - .getSucceeded(); - if (succeeded) { - runSynchronizeOperation(new AfterDeactivateSingleAsyncOperationFactory(), - _isLastMaster, - _newMasterStorageDomainId); - if (_isLastMaster && spm != null) { - final VDSReturnValue stopSpmReturnValue = getBackend() - .getResourceManager() - .RunVdsCommand(VDSCommandType.SpmStopOnIrs, - new IrsBaseVDSCommandParameters(getStoragePool().getId())); - if (!stopSpmReturnValue.getSucceeded()) { - // no need to continue because DisconnectStoragePool will - // fail if host is SPM - log.error("Aborting execution due to failure stopping SPM." + - " Stop SPM failed due to " - + stopSpmReturnValue.getExceptionString()); - setSucceeded(false); - return; - } - getBackend().getResourceManager() - .RunVdsCommand( - VDSCommandType.DisconnectStoragePool, - new DisconnectStoragePoolVDSCommandParameters(spm.getId(), - getStoragePool().getId(), spm.getvds_spm_id())); + runVdsCommand(VDSCommandType.DeactivateStorageDomain, + new DeactivateStorageDomainVDSCommandParameters(getStoragePool().getId(), + getStorageDomain() + .getId(), + _newMasterStorageDomainId, + getStoragePool().getmaster_domain_version())); + freeLock(); + runSynchronizeOperation(new AfterDeactivateSingleAsyncOperationFactory(), + _isLastMaster, + _newMasterStorageDomainId); + if (_isLastMaster && spm != null) { + final VDSReturnValue stopSpmReturnValue = runVdsCommand(VDSCommandType.SpmStopOnIrs, + new IrsBaseVDSCommandParameters(getStoragePool().getId())); + if (!stopSpmReturnValue.getSucceeded()) { + // no need to continue because DisconnectStoragePool will + // fail if host is SPM + log.error("Aborting execution due to failure stopping SPM." + + " Stop SPM failed due to " + + stopSpmReturnValue.getExceptionString()); + setSucceeded(false); + return; } - - getStorageHelper(getStorageDomain()).DisconnectStorageFromDomainByVdsId(getStorageDomain(), spm.getId()); - - executeInNewTransaction(new TransactionMethod<Object>() { - @Override - public Object runInTransaction() { - getCompensationContext().snapshotEntityStatus(map, map.getstatus()); - if (getParameters().isInactive()) { - map.setstatus(StorageDomainStatus.InActive); - } else { - map.setstatus(StorageDomainStatus.Maintenance); - } - getStoragePoolIsoMapDAO().updateStatus(map.getId(), map.getstatus()); - if (!Guid.Empty.equals(_newMasterStorageDomainId)) { - storage_pool_iso_map mapOfNewMaster = getNewMaster(false).getStoragePoolIsoMapData(); - getCompensationContext().snapshotEntityStatus(mapOfNewMaster, mapOfNewMaster.getstatus()); - mapOfNewMaster.setstatus(StorageDomainStatus.Active); - getStoragePoolIsoMapDAO().updateStatus(mapOfNewMaster.getId(), mapOfNewMaster.getstatus()); - } - getCompensationContext().stateChanged(); - return null; - } - }); - setSucceeded(true); + runVdsCommand(VDSCommandType.DisconnectStoragePool, + new DisconnectStoragePoolVDSCommandParameters(spm.getId(), + getStoragePool().getId(), spm.getvds_spm_id())); } + + if (spm != null) { + getStorageHelper(getStorageDomain()).DisconnectStorageFromDomainByVdsId(getStorageDomain(), spm.getId()); + } + + executeInNewTransaction(new TransactionMethod<Object>() { + @Override + public Object runInTransaction() { + if (getParameters().isInactive()) { + map.setstatus(StorageDomainStatus.InActive); + } else { + map.setstatus(StorageDomainStatus.Maintenance); + } + getStoragePoolIsoMapDAO().updateStatus(map.getId(), map.getstatus()); + if (!Guid.Empty.equals(_newMasterStorageDomainId)) { + storage_pool_iso_map mapOfNewMaster = getNewMaster(false).getStoragePoolIsoMapData(); + mapOfNewMaster.setstatus(StorageDomainStatus.Active); + getStoragePoolIsoMapDAO().updateStatus(mapOfNewMaster.getId(), mapOfNewMaster.getstatus()); + } + return null; + } + }); + setSucceeded(true); } /** @@ -273,7 +273,7 @@ } } - AsyncTaskDAO getAsyncTaskDao() { + protected AsyncTaskDAO getAsyncTaskDao() { return DbFacade.getInstance().getAsyncTaskDAO(); } @@ -284,4 +284,29 @@ : getSucceeded() ? AuditLogType.USER_DEACTIVATED_STORAGE_DOMAIN : AuditLogType.USER_DEACTIVATE_STORAGE_DOMAIN_FAILED; } + + @Override + protected Map<String, String> getExclusiveLocks() { + storage_domains storageDomain = getStorageDomain(); + if (storageDomain != null) { + Map<String, String> locks = new HashMap<String, String>(); + locks.put(storageDomain.getId().toString(), LockingGroup.STORAGE.name()); + if (storageDomain.getstorage_domain_type() == StorageDomainType.Master) { + locks.put(storageDomain.getstorage_pool_id().toString(), LockingGroup.POOL.name()); + } + return locks; + } + return null; + } + + @Override + protected Map<String, String> getSharedLocks() { + storage_domains storageDomain = getStorageDomain(); + if (storageDomain != null && storageDomain.getstorage_domain_type() == StorageDomainType.Data + && storageDomain.getstorage_domain_type() != StorageDomainType.Master + && storageDomain.getstorage_pool_id() != null) { + return Collections.singletonMap(storageDomain.getstorage_pool_id().toString(), LockingGroup.POOL.name()); + } + return null; + } } diff --git a/backend/manager/modules/dal/src/main/java/org/ovirt/engine/core/dal/VdcBllMessages.java b/backend/manager/modules/dal/src/main/java/org/ovirt/engine/core/dal/VdcBllMessages.java index 9171781..e5d73a0 100644 --- a/backend/manager/modules/dal/src/main/java/org/ovirt/engine/core/dal/VdcBllMessages.java +++ b/backend/manager/modules/dal/src/main/java/org/ovirt/engine/core/dal/VdcBllMessages.java @@ -200,6 +200,7 @@ VDS_CANNOT_INSTALL_MISSING_IMAGE_FILE, VDS_CANNOT_CONNECT_TO_SERVER, VAR__ACTION__MANUAL_FENCE, + VAR__ACTION__MAINTENANCE, ACTION_TYPE_FAILED_PM_ENABLED_WITHOUT_AGENT, ACTION_TYPE_FAILED_PM_ENABLED_WITHOUT_AGENT_CREDENTIALS, ACTION_TYPE_FAILED_AGENT_NOT_SUPPORTED, diff --git a/backend/manager/modules/dal/src/main/resources/bundles/AppErrors.properties b/backend/manager/modules/dal/src/main/resources/bundles/AppErrors.properties index 3e31491..fbb83e9 100644 --- a/backend/manager/modules/dal/src/main/resources/bundles/AppErrors.properties +++ b/backend/manager/modules/dal/src/main/resources/bundles/AppErrors.properties @@ -240,6 +240,7 @@ VAR__ACTION__EJECT_CD=$action Eject CD VAR__ACTION__ALLOCATE_AND_RUN=$action allocate and run VAR__ACTION__MANUAL_FENCE=$action confirm 'Host has been rebooted' +VAR__ACTION__MAINTENANCE=$action maintenance VAR__ACTION__SET=$action set VAR__ACTION__RESET=$action reset VAR__ACTION__SETUP=$action setup diff --git a/frontend/webadmin/modules/frontend/src/main/java/org/ovirt/engine/ui/frontend/AppErrors.java b/frontend/webadmin/modules/frontend/src/main/java/org/ovirt/engine/ui/frontend/AppErrors.java index 54bea2c..fc27235 100644 --- a/frontend/webadmin/modules/frontend/src/main/java/org/ovirt/engine/ui/frontend/AppErrors.java +++ b/frontend/webadmin/modules/frontend/src/main/java/org/ovirt/engine/ui/frontend/AppErrors.java @@ -634,6 +634,9 @@ @DefaultStringValue("$action confirm 'Host has been rebooted'") String VAR__ACTION__MANUAL_FENCE(); + @DefaultStringValue("$action maintenance") + String VAR__ACTION__MAINTENANCE(); + @DefaultStringValue("$action setup") String VAR__ACTION__SETUP(); diff --git a/frontend/webadmin/modules/userportal-gwtp/src/main/resources/org/ovirt/engine/ui/frontend/AppErrors.properties b/frontend/webadmin/modules/userportal-gwtp/src/main/resources/org/ovirt/engine/ui/frontend/AppErrors.properties index 2e96cdd..16940fc 100644 --- a/frontend/webadmin/modules/userportal-gwtp/src/main/resources/org/ovirt/engine/ui/frontend/AppErrors.properties +++ b/frontend/webadmin/modules/userportal-gwtp/src/main/resources/org/ovirt/engine/ui/frontend/AppErrors.properties @@ -239,6 +239,7 @@ VAR__ACTION__EJECT_CD=$action Eject CD VAR__ACTION__ALLOCATE_AND_RUN=$action allocate and run VAR__ACTION__MANUAL_FENCE=$action confirm 'Host has been rebooted' +VAR__ACTION__MAINTENANCE=$action maintenance VAR__ACTION__SET=$action set VAR__ACTION__SETUP=$action setup VAR__ACTION__UPDATE=$action edit diff --git a/frontend/webadmin/modules/webadmin/src/main/resources/org/ovirt/engine/ui/frontend/AppErrors.properties b/frontend/webadmin/modules/webadmin/src/main/resources/org/ovirt/engine/ui/frontend/AppErrors.properties index 7188f9a..2da16c8 100644 --- a/frontend/webadmin/modules/webadmin/src/main/resources/org/ovirt/engine/ui/frontend/AppErrors.properties +++ b/frontend/webadmin/modules/webadmin/src/main/resources/org/ovirt/engine/ui/frontend/AppErrors.properties @@ -237,6 +237,7 @@ VAR__ACTION__EJECT_CD=$action Eject CD VAR__ACTION__ALLOCATE_AND_RUN=$action allocate and run VAR__ACTION__MANUAL_FENCE=$action confirm 'Host has been rebooted' +VAR__ACTION__MAINTENANCE=$action maintenance VAR__ACTION__SET=$action set VAR__ACTION__SETUP=$action setup VAR__ACTION__UPDATE=$action edit -- To view, visit http://gerrit.ovirt.org/7172 To unsubscribe, visit http://gerrit.ovirt.org/settings Gerrit-MessageType: newchange Gerrit-Change-Id: Ia929d8cfab5904cb8e66d18cf50e037d36d8d373 Gerrit-PatchSet: 1 Gerrit-Project: ovirt-engine Gerrit-Branch: master Gerrit-Owner: Michael Kublin <mkub...@redhat.com> _______________________________________________ Engine-patches mailing list Engine-patches@ovirt.org http://lists.ovirt.org/mailman/listinfo/engine-patches