mirror of https://github.com/apache/cloudstack.git
vmware: improve support for disk controllers
- Improve disk chain usage while attaching, migrating disks - Gets root disk controller based diskDeviceBusName from volume's chain info Signed-off-by: Rohit Yadav <rohit.yadav@shapeblue.com>
This commit is contained in:
parent
dd2d8867a9
commit
b6a6add9b7
|
|
@ -24,6 +24,7 @@ import com.cloud.agent.api.Command;
|
|||
|
||||
public class MigrateVolumeAnswer extends Answer {
|
||||
private String volumePath;
|
||||
private String volumeChain;
|
||||
|
||||
public MigrateVolumeAnswer(Command command, boolean success, String details, String volumePath) {
|
||||
super(command, success, details);
|
||||
|
|
@ -38,4 +39,12 @@ public class MigrateVolumeAnswer extends Answer {
|
|||
public String getVolumePath() {
|
||||
return volumePath;
|
||||
}
|
||||
|
||||
public String getVolumeChainInfo() {
|
||||
return volumeChain;
|
||||
}
|
||||
|
||||
public void setVolumeChainInfo(String volumeChain) {
|
||||
this.volumeChain = volumeChain;
|
||||
}
|
||||
}
|
||||
|
|
@ -22,8 +22,11 @@ package org.apache.cloudstack.storage.command;
|
|||
import com.cloud.agent.api.Answer;
|
||||
import com.cloud.agent.api.to.DiskTO;
|
||||
|
||||
import java.util.Map;
|
||||
|
||||
public class AttachAnswer extends Answer {
|
||||
private DiskTO disk;
|
||||
private Map<String, String> diskDetails;
|
||||
|
||||
public AttachAnswer() {
|
||||
super(null);
|
||||
|
|
@ -34,6 +37,12 @@ public class AttachAnswer extends Answer {
|
|||
setDisk(disk);
|
||||
}
|
||||
|
||||
public AttachAnswer(DiskTO disk, Map<String, String> diskDetails) {
|
||||
super(null);
|
||||
setDisk(disk);
|
||||
setDiskDetails(diskDetails);
|
||||
}
|
||||
|
||||
public AttachAnswer(String errMsg) {
|
||||
super(null, false, errMsg);
|
||||
}
|
||||
|
|
@ -45,4 +54,12 @@ public class AttachAnswer extends Answer {
|
|||
public void setDisk(DiskTO disk) {
|
||||
this.disk = disk;
|
||||
}
|
||||
|
||||
public Map<String, String> getDiskDetails() {
|
||||
return diskDetails;
|
||||
}
|
||||
|
||||
public void setDiskDetails(Map<String, String> diskDetails) {
|
||||
this.diskDetails = diskDetails;
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -407,6 +407,10 @@ public class AncientDataMotionStrategy implements DataMotionStrategy {
|
|||
VolumeVO volumeVo = volDao.findById(volume.getId());
|
||||
Long oldPoolId = volume.getPoolId();
|
||||
volumeVo.setPath(((MigrateVolumeAnswer)answer).getVolumePath());
|
||||
String chainInfo = ((MigrateVolumeAnswer) answer).getVolumeChainInfo();
|
||||
if (chainInfo != null) {
|
||||
volumeVo.setChainInfo(chainInfo);
|
||||
}
|
||||
volumeVo.setPodId(destPool.getPodId());
|
||||
volumeVo.setPoolId(destPool.getId());
|
||||
volumeVo.setLastPoolId(oldPoolId);
|
||||
|
|
|
|||
|
|
@ -207,6 +207,9 @@ public class VmwareStorageMotionStrategy implements DataMotionStrategy {
|
|||
VolumeVO volumeVO = volDao.findById(volume.getId());
|
||||
Long oldPoolId = volumeVO.getPoolId();
|
||||
volumeVO.setPath(volumeTo.getPath());
|
||||
if (volumeTo.getChainInfo() != null) {
|
||||
volumeVO.setChainInfo(volumeTo.getChainInfo());
|
||||
}
|
||||
volumeVO.setLastPoolId(oldPoolId);
|
||||
volumeVO.setFolder(pool.getPath());
|
||||
volumeVO.setPodId(pool.getPodId());
|
||||
|
|
|
|||
|
|
@ -26,6 +26,7 @@ import java.util.concurrent.ExecutionException;
|
|||
|
||||
import javax.inject.Inject;
|
||||
|
||||
import org.apache.cloudstack.utils.volume.VirtualMachineVolumeChainInfo;
|
||||
import org.apache.log4j.Logger;
|
||||
|
||||
import org.apache.cloudstack.api.command.user.volume.AttachVolumeCmd;
|
||||
|
|
@ -96,16 +97,19 @@ import com.cloud.exception.StorageUnavailableException;
|
|||
import com.cloud.gpu.GPU;
|
||||
import com.cloud.host.HostVO;
|
||||
import com.cloud.host.dao.HostDao;
|
||||
import com.cloud.hypervisor.Hypervisor;
|
||||
import com.cloud.hypervisor.Hypervisor.HypervisorType;
|
||||
import com.cloud.hypervisor.HypervisorCapabilitiesVO;
|
||||
import com.cloud.hypervisor.dao.HypervisorCapabilitiesDao;
|
||||
import com.cloud.org.Grouping;
|
||||
import com.cloud.serializer.GsonHelper;
|
||||
import com.cloud.service.dao.ServiceOfferingDetailsDao;
|
||||
import com.cloud.storage.Storage.ImageFormat;
|
||||
import com.cloud.storage.dao.DiskOfferingDao;
|
||||
import com.cloud.storage.dao.SnapshotDao;
|
||||
import com.cloud.storage.dao.VMTemplateDao;
|
||||
import com.cloud.storage.dao.VolumeDao;
|
||||
import com.cloud.storage.dao.VolumeDetailsDao;
|
||||
import com.cloud.storage.snapshot.SnapshotApiService;
|
||||
import com.cloud.storage.snapshot.SnapshotManager;
|
||||
import com.cloud.template.TemplateManager;
|
||||
|
|
@ -134,6 +138,7 @@ import com.cloud.utils.db.UUIDManager;
|
|||
import com.cloud.utils.exception.CloudRuntimeException;
|
||||
import com.cloud.utils.fsm.NoTransitionException;
|
||||
import com.cloud.utils.fsm.StateMachine2;
|
||||
import com.cloud.vm.UserVmManager;
|
||||
import com.cloud.vm.UserVmVO;
|
||||
import com.cloud.vm.VMInstanceVO;
|
||||
import com.cloud.vm.VirtualMachine;
|
||||
|
|
@ -154,6 +159,8 @@ import com.cloud.vm.dao.UserVmDao;
|
|||
import com.cloud.vm.dao.VMInstanceDao;
|
||||
import com.cloud.vm.snapshot.VMSnapshotVO;
|
||||
import com.cloud.vm.snapshot.dao.VMSnapshotDao;
|
||||
import com.google.gson.Gson;
|
||||
import com.google.gson.JsonParseException;
|
||||
|
||||
public class VolumeApiServiceImpl extends ManagerBase implements VolumeApiService, VmWorkJobHandler {
|
||||
private final static Logger s_logger = Logger.getLogger(VolumeApiServiceImpl.class);
|
||||
|
|
@ -176,6 +183,8 @@ public class VolumeApiServiceImpl extends ManagerBase implements VolumeApiServic
|
|||
@Inject
|
||||
VolumeDao _volsDao;
|
||||
@Inject
|
||||
VolumeDetailsDao _volDetailDao;
|
||||
@Inject
|
||||
HostDao _hostDao;
|
||||
@Inject
|
||||
SnapshotDao _snapshotDao;
|
||||
|
|
@ -225,6 +234,9 @@ public class VolumeApiServiceImpl extends ManagerBase implements VolumeApiServic
|
|||
VmWorkJobDao _workJobDao;
|
||||
@Inject
|
||||
ClusterDetailsDao _clusterDetailsDao;
|
||||
@Inject
|
||||
UserVmManager _userVmMgr;
|
||||
protected Gson _gson;
|
||||
|
||||
private List<StoragePoolAllocator> _storagePoolAllocators;
|
||||
|
||||
|
|
@ -238,6 +250,7 @@ public class VolumeApiServiceImpl extends ManagerBase implements VolumeApiServic
|
|||
|
||||
protected VolumeApiServiceImpl() {
|
||||
_volStateMachine = Volume.State.getStateMachine();
|
||||
_gson = GsonHelper.getGsonLogger();
|
||||
}
|
||||
|
||||
/*
|
||||
|
|
@ -1781,6 +1794,23 @@ public class VolumeApiServiceImpl extends ManagerBase implements VolumeApiServic
|
|||
throw new InvalidParameterValueException("Cannot migrate ROOT volume of a stopped VM to a storage pool in a different VMware datacenter");
|
||||
}
|
||||
}
|
||||
|
||||
String rootVolChainInfo = vol.getChainInfo();
|
||||
if ((vm.getType().equals(VirtualMachine.Type.User)) && (rootVolChainInfo != null) && (!rootVolChainInfo.isEmpty())) {
|
||||
String rootDiskController = null;
|
||||
try {
|
||||
VirtualMachineVolumeChainInfo infoInChain = _gson.fromJson(rootVolChainInfo, VirtualMachineVolumeChainInfo.class);
|
||||
if (infoInChain != null) {
|
||||
rootDiskController = infoInChain.getControllerFromDeviceBusName();
|
||||
}
|
||||
UserVmVO userVmVo = _userVmDao.findById(vm.getId());
|
||||
if ((rootDiskController != null) && (!rootDiskController.isEmpty())) {
|
||||
_userVmDao.loadDetails(userVmVo);
|
||||
_userVmMgr.persistDeviceBusInfo(userVmVo, rootDiskController);
|
||||
}
|
||||
} catch (JsonParseException ignored) {
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -2349,6 +2379,15 @@ public class VolumeApiServiceImpl extends ManagerBase implements VolumeApiServic
|
|||
|
||||
_volsDao.update(volumeToAttach.getId(), volumeToAttach);
|
||||
}
|
||||
|
||||
if (host.getHypervisorType() == Hypervisor.HypervisorType.VMware) {
|
||||
Map<String, String> diskDetails = answer.getDiskDetails();
|
||||
for (Map.Entry<String, String> detail : diskDetails.entrySet()) {
|
||||
VolumeDetailVO volumeDetailVo = new VolumeDetailVO(volumeToAttach.getId(), detail.getKey(), detail.getValue(), true);
|
||||
_volDetailDao.persist(volumeDetailVo);
|
||||
}
|
||||
}
|
||||
|
||||
} else {
|
||||
_volsDao.attachVolume(volumeToAttach.getId(), vm.getId(), deviceId);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -111,4 +111,6 @@ public interface UserVmManager extends UserVmService {
|
|||
public void removeCustomOfferingDetails(long vmId);
|
||||
|
||||
void generateUsageEvent(VirtualMachine vm, boolean isDisplay, String eventType);
|
||||
|
||||
void persistDeviceBusInfo(UserVmVO paramUserVmVO, String paramString);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -5028,6 +5028,15 @@ public class UserVmManagerImpl extends ManagerBase implements UserVmManager, Vir
|
|||
}
|
||||
}
|
||||
|
||||
public void persistDeviceBusInfo(UserVmVO vm, String rootDiskController) {
|
||||
String existingVmRootDiskController = vm.getDetail(VmDetailConstants.ROOK_DISK_CONTROLLER);
|
||||
if (((existingVmRootDiskController == null) || (existingVmRootDiskController.isEmpty())) && (rootDiskController != null) && (!rootDiskController.isEmpty())) {
|
||||
vm.setDetail(VmDetailConstants.ROOK_DISK_CONTROLLER, rootDiskController);
|
||||
_vmDao.saveDetails(vm);
|
||||
s_logger.debug("Persisted device bus information rootDiskController=" + rootDiskController + " for vm: " + vm.getDisplayName());
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getConfigComponentName() {
|
||||
return UserVmManager.class.getSimpleName();
|
||||
|
|
|
|||
|
|
@ -0,0 +1,48 @@
|
|||
//
|
||||
// Licensed to the Apache Software Foundation (ASF) under one
|
||||
// or more contributor license agreements. See the NOTICE file
|
||||
// distributed with this work for additional information
|
||||
// regarding copyright ownership. The ASF licenses this file
|
||||
// to you under the Apache License, Version 2.0 (the
|
||||
// "License"); you may not use this file except in compliance
|
||||
// with the License. You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing,
|
||||
// software distributed under the License is distributed on an
|
||||
// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
|
||||
// KIND, either express or implied. See the License for the
|
||||
// specific language governing permissions and limitations
|
||||
// under the License.
|
||||
//
|
||||
|
||||
package org.apache.cloudstack.utils.volume;
|
||||
|
||||
public class VirtualMachineVolumeChainInfo {
|
||||
String diskDeviceBusName;
|
||||
String[] diskChain;
|
||||
|
||||
public String getDiskDeviceBusName() {
|
||||
return this.diskDeviceBusName;
|
||||
}
|
||||
|
||||
public void setDiskDeviceBusName(String diskDeviceBusName) {
|
||||
this.diskDeviceBusName = diskDeviceBusName;
|
||||
}
|
||||
|
||||
public String[] getDiskChain() {
|
||||
return this.diskChain;
|
||||
}
|
||||
|
||||
public void setDiskChain(String[] diskChain) {
|
||||
this.diskChain = diskChain;
|
||||
}
|
||||
|
||||
public String getControllerFromDeviceBusName() {
|
||||
if ((this.diskDeviceBusName == null) || (this.diskDeviceBusName.isEmpty()) || (!this.diskDeviceBusName.contains(":"))) {
|
||||
return null;
|
||||
}
|
||||
return this.diskDeviceBusName.substring(0, this.diskDeviceBusName.indexOf(":") - 1);
|
||||
}
|
||||
}
|
||||
Loading…
Reference in New Issue