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 <abhishek.mrt22@gmail.com>

* typo

Co-authored-by: sureshanaparti <12028987+sureshanaparti@users.noreply.github.com>

Co-authored-by: sureshanaparti <12028987+sureshanaparti@users.noreply.github.com>
This commit is contained in:
Abhishek Kumar 2021-08-31 06:57:45 +05:30 committed by GitHub
parent d8a961e522
commit fc213ac9fd
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
1 changed files with 33 additions and 21 deletions

View File

@ -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<Long, Long> 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<HostVO> 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) {