From fc213ac9fd7a6791d966df3b660e65523b0605c6 Mon Sep 17 00:00:00 2001 From: Abhishek Kumar Date: Tue, 31 Aug 2021 06:57:45 +0530 Subject: [PATCH] server: improve attach volume in specific cases (#5371) * server: improve attach volume in specific cases When a VM is in stopped state and host for it is not found then server skips sending AttachCommand to hypervisor. Change tries to improve this case and finds a suitable host in the VM's cluster when volume is not in a HOST scope pool. Signed-off-by: Abhishek Kumar * typo Co-authored-by: sureshanaparti <12028987+sureshanaparti@users.noreply.github.com> Co-authored-by: sureshanaparti <12028987+sureshanaparti@users.noreply.github.com> --- .../cloud/storage/VolumeApiServiceImpl.java | 54 +++++++++++-------- 1 file changed, 33 insertions(+), 21 deletions(-) diff --git a/server/src/main/java/com/cloud/storage/VolumeApiServiceImpl.java b/server/src/main/java/com/cloud/storage/VolumeApiServiceImpl.java index 96e07edd553..7d2575d1509 100644 --- a/server/src/main/java/com/cloud/storage/VolumeApiServiceImpl.java +++ b/server/src/main/java/com/cloud/storage/VolumeApiServiceImpl.java @@ -33,8 +33,6 @@ import java.util.concurrent.ExecutionException; import javax.inject.Inject; -import com.cloud.api.query.dao.ServiceOfferingJoinDao; -import com.cloud.api.query.vo.ServiceOfferingJoinVO; import org.apache.cloudstack.api.command.user.volume.AttachVolumeCmd; import org.apache.cloudstack.api.command.user.volume.CreateVolumeCmd; import org.apache.cloudstack.api.command.user.volume.DetachVolumeCmd; @@ -101,6 +99,8 @@ import com.cloud.agent.api.ModifyTargetsCommand; import com.cloud.agent.api.to.DataTO; import com.cloud.agent.api.to.DiskTO; import com.cloud.api.ApiDBUtils; +import com.cloud.api.query.dao.ServiceOfferingJoinDao; +import com.cloud.api.query.vo.ServiceOfferingJoinVO; import com.cloud.configuration.Config; import com.cloud.configuration.ConfigurationManager; import com.cloud.configuration.Resource.ResourceType; @@ -176,6 +176,7 @@ import com.cloud.vm.UserVmVO; import com.cloud.vm.VMInstanceVO; import com.cloud.vm.VirtualMachine; import com.cloud.vm.VirtualMachine.State; +import com.cloud.vm.VirtualMachineManager; import com.cloud.vm.VmDetailConstants; import com.cloud.vm.VmWork; import com.cloud.vm.VmWorkAttachVolume; @@ -288,6 +289,8 @@ public class VolumeApiServiceImpl extends ManagerBase implements VolumeApiServic private StorageUtil storageUtil; @Inject public TaggedResourceService taggedResourceService; + @Inject + VirtualMachineManager virtualMachineManager; protected Gson _gson; @@ -3218,31 +3221,40 @@ public class VolumeApiServiceImpl extends ManagerBase implements VolumeApiServic return "clustered file systems"; } + private HostVO getHostForVmVolumeAttach(UserVmVO vm, StoragePoolVO volumeToAttachStoragePool) { + HostVO host = null; + Pair clusterAndHostId = virtualMachineManager.findClusterAndHostIdForVm(vm.getId()); + Long hostId = clusterAndHostId.second(); + Long clusterId = clusterAndHostId.first(); + if (hostId == null && clusterId != null && + State.Stopped.equals(vm.getState()) && + volumeToAttachStoragePool != null && + !ScopeType.HOST.equals(volumeToAttachStoragePool.getScope())) { + List hosts = _hostDao.findHypervisorHostInCluster(clusterId); + if (!hosts.isEmpty()) { + host = hosts.get(0); + } + } + if (host == null && hostId != null) { + host = _hostDao.findById(hostId); + } + return host; + } + private VolumeVO sendAttachVolumeCommand(UserVmVO vm, VolumeVO volumeToAttach, Long deviceId) { String errorMsg = "Failed to attach volume " + volumeToAttach.getName() + " to VM " + vm.getHostName(); boolean sendCommand = vm.getState() == State.Running; AttachAnswer answer = null; - Long hostId = vm.getHostId(); - - if (hostId == null) { - hostId = vm.getLastHostId(); - - HostVO host = _hostDao.findById(hostId); - - if (host != null && host.getHypervisorType() == HypervisorType.VMware) { - sendCommand = true; - } + StoragePoolVO volumeToAttachStoragePool = _storagePoolDao.findById(volumeToAttach.getPoolId()); + HostVO host = getHostForVmVolumeAttach(vm, volumeToAttachStoragePool); + Long hostId = host == null ? null : host.getId(); + if (host != null && host.getHypervisorType() == HypervisorType.VMware) { + sendCommand = true; } - HostVO host = null; - StoragePoolVO volumeToAttachStoragePool = _storagePoolDao.findById(volumeToAttach.getPoolId()); - - if (hostId != null) { - host = _hostDao.findById(hostId); - - if (host != null && host.getHypervisorType() == HypervisorType.XenServer && volumeToAttachStoragePool != null && volumeToAttachStoragePool.isManaged()) { - sendCommand = true; - } + if (host != null && host.getHypervisorType() == HypervisorType.XenServer && + volumeToAttachStoragePool != null && volumeToAttachStoragePool.isManaged()) { + sendCommand = true; } if (volumeToAttachStoragePool != null) {