Fix startcommand on Datastore cluster when the volume datastore in CloudStack mismatches with vCenter datastore. Volume could have migrated with in datastore cluster which caused the mismatch

Fix dettach volume when volume is not on CloudStack intended datastore
This commit is contained in:
Harikrishna Patnala 2020-09-29 00:49:35 +05:30
parent 6e81efa2c9
commit 9543fd6e6a
11 changed files with 233 additions and 77 deletions

View File

@ -39,7 +39,7 @@ public class PrimaryDataStoreTO implements DataStoreTO {
public static final String REMOVE_AFTER_COPY = PrimaryDataStore.REMOVE_AFTER_COPY;
public static final String VOLUME_SIZE = PrimaryDataStore.VOLUME_SIZE;
private final String uuid;
private String uuid;
private final String name;
private String type;
private final long id;
@ -75,6 +75,10 @@ public class PrimaryDataStoreTO implements DataStoreTO {
return this.uuid;
}
public void setUuid(String uuid) {
this.uuid = uuid;
}
@Override
public String getUrl() {
return this.url;

View File

@ -63,6 +63,7 @@ public class VolumeObjectTO implements DataTO {
private MigrationOptions migrationOptions;
private boolean directDownload;
private boolean deployAsIs;
private String updatedDataStoreUUID;
public VolumeObjectTO() {
@ -319,4 +320,13 @@ public class VolumeObjectTO implements DataTO {
public boolean isDeployAsIs() {
return deployAsIs;
}
public String getUpdatedDataStoreUUID() {
return updatedDataStoreUUID;
}
public void setUpdatedDataStoreUUID(String updatedDataStoreUUID) {
this.updatedDataStoreUUID = updatedDataStoreUUID;
}
}

View File

@ -134,7 +134,7 @@ public interface VolumeOrchestrationService {
StoragePool findStoragePool(DiskProfile dskCh, DataCenter dc, Pod pod, Long clusterId, Long hostId, VirtualMachine vm, Set<StoragePool> avoid);
void updateVolumeDiskChain(long volumeId, String path, String chainInfo);
void updateVolumeDiskChain(long volumeId, String path, String chainInfo, String updatedDataStoreUUID);
/**
* Imports an existing volume for a VM into database. Useful while ingesting an unmanaged VM.

View File

@ -1491,9 +1491,9 @@ public class VirtualMachineManagerImpl extends ManagerBase implements VirtualMac
// Before doing this, in a certain situation, getPath() from VolumeObjectTO
// returned null instead of an actual path (because it was out of date with the DB).
if(vol.getPath() != null) {
volumeMgr.updateVolumeDiskChain(vol.getId(), vol.getPath(), vol.getChainInfo());
volumeMgr.updateVolumeDiskChain(vol.getId(), vol.getPath(), vol.getChainInfo(), vol.getUpdatedDataStoreUUID());
} else {
volumeMgr.updateVolumeDiskChain(vol.getId(), volume.getPath(), vol.getChainInfo());
volumeMgr.updateVolumeDiskChain(vol.getId(), volume.getPath(), vol.getChainInfo(), vol.getUpdatedDataStoreUUID());
}
}
}

View File

@ -1238,9 +1238,15 @@ public class VolumeOrchestrator extends ManagerBase implements VolumeOrchestrati
details.put(DiskTO.MOUNT_POINT, volumeInfo.get_iScsiName());
VolumeVO volume = _volumeDao.findById(volumeInfo.getId());
details.put(DiskTO.PROTOCOL_TYPE, (volume.getPoolType() != null) ? volume.getPoolType().toString() : null);
if (volume.getPoolId() != null) {
StoragePoolVO poolVO = _storagePoolDao.findById(volume.getPoolId());
if (poolVO.getParent() != 0L) {
details.put(DiskTO.PROTOCOL_TYPE, Storage.StoragePoolType.DatastoreCluster.toString());
}
}
ChapInfo chapInfo = volService.getChapInfo(volumeInfo, dataStore);
if (chapInfo != null) {
@ -1704,7 +1710,7 @@ public class VolumeOrchestrator extends ManagerBase implements VolumeOrchestrati
}
@Override
public void updateVolumeDiskChain(long volumeId, String path, String chainInfo) {
public void updateVolumeDiskChain(long volumeId, String path, String chainInfo, String updatedDataStoreUUID) {
VolumeVO vol = _volsDao.findById(volumeId);
boolean needUpdate = false;
// Volume path is not getting updated in the DB, need to find reason and fix the issue.
@ -1719,10 +1725,20 @@ public class VolumeOrchestrator extends ManagerBase implements VolumeOrchestrati
needUpdate = true;
}
if (updatedDataStoreUUID != null) {
needUpdate = true;
}
if (needUpdate) {
s_logger.info("Update volume disk chain info. vol: " + vol.getId() + ", " + vol.getPath() + " -> " + path + ", " + vol.getChainInfo() + " -> " + chainInfo);
vol.setPath(path);
vol.setChainInfo(chainInfo);
if (updatedDataStoreUUID != null) {
List<StoragePoolVO> pools = _storagePoolDao.listPoolsByLikePath(updatedDataStoreUUID);
if (pools != null && !pools.isEmpty()) {
vol.setPoolId(pools.get(0).getId());
}
}
_volsDao.update(volumeId, vol);
}
}

View File

@ -127,4 +127,6 @@ public interface PrimaryDataStoreDao extends GenericDao<StoragePoolVO, Long> {
List<StoragePoolVO> listChildStoragePoolsInDatastoreCluster(long poolId);
Integer countAll();
public List<StoragePoolVO> listPoolsByLikePath(String path);
}

View File

@ -56,6 +56,7 @@ public class PrimaryDataStoreDaoImpl extends GenericDaoBase<StoragePoolVO, Long>
private final SearchBuilder<StoragePoolVO> DeleteLvmSearch;
private final SearchBuilder<StoragePoolVO> DcLocalStorageSearch;
private final GenericSearchBuilder<StoragePoolVO, Long> StatusCountSearch;
private final SearchBuilder<StoragePoolVO> PathLikeSearch;
@Inject
private StoragePoolDetailsDao _detailsDao;
@ -132,6 +133,17 @@ public class PrimaryDataStoreDaoImpl extends GenericDaoBase<StoragePoolVO, Long>
DcLocalStorageSearch.and("path", DcLocalStorageSearch.entity().getPath(), SearchCriteria.Op.EQ);
DcLocalStorageSearch.and("scope", DcLocalStorageSearch.entity().getScope(), SearchCriteria.Op.EQ);
DcLocalStorageSearch.done();
PathLikeSearch = createSearchBuilder();
PathLikeSearch.and("path", PathLikeSearch.entity().getPath(), SearchCriteria.Op.LIKE);
PathLikeSearch.done();
}
@Override
public List<StoragePoolVO> listPoolsByLikePath(String path) {
SearchCriteria<StoragePoolVO> sc = PathLikeSearch.create();
sc.setParameters("path", "%" + path + "%");
return listBy(sc);
}
@Override

View File

@ -1791,13 +1791,6 @@ public class VmwareResource implements StoragePoolResource, ServerResource, Vmwa
throw new Exception(msg);
}
DatastoreMO dsRootVolumeIsOn = getDatastoreThatRootDiskIsOn(dataStoresDetails, disks);
if (dsRootVolumeIsOn == null) {
String msg = "Unable to locate datastore details of root volume";
s_logger.error(msg);
throw new Exception(msg);
}
VirtualMachineDiskInfoBuilder diskInfoBuilder = null;
VirtualDevice[] nicDevices = null;
VirtualMachineMO vmMo = hyperHost.findVmOnHyperHost(vmInternalCSName);
@ -1806,12 +1799,14 @@ public class VmwareResource implements StoragePoolResource, ServerResource, Vmwa
int numScsiControllerForSystemVm = 1;
boolean hasSnapshot = false;
List<Pair<Integer, ManagedObjectReference>> diskDatastores = null;
if (vmMo != null) {
s_logger.info("VM " + vmInternalCSName + " already exists, tear down devices for reconfiguration");
if (getVmPowerState(vmMo) != PowerState.PowerOff)
vmMo.safePowerOff(_shutdownWaitMs);
// retrieve disk information before we tear down
diskDatastores = vmMo.getAllDiskDatastores();
diskInfoBuilder = vmMo.getDiskInfoBuilder();
hasSnapshot = vmMo.hasSnapshot();
nicDevices = vmMo.getNicDevices();
@ -1836,6 +1831,7 @@ public class VmwareResource implements StoragePoolResource, ServerResource, Vmwa
diskInfoBuilder = vmMo.getDiskInfoBuilder();
hasSnapshot = vmMo.hasSnapshot();
diskDatastores = vmMo.getAllDiskDatastores();
tearDownVmDevices(vmMo, hasSnapshot, deployAsIs);
ensureDiskControllersInternal(vmMo, systemVm, controllerInfo, systemVmScsiControllerType,
@ -1866,32 +1862,33 @@ public class VmwareResource implements StoragePoolResource, ServerResource, Vmwa
}
mapSpecDisksToClonedDisks(vmMo, vmInternalCSName, specDisks);
} else {
Pair<ManagedObjectReference, DatastoreMO> rootDiskDataStoreDetails = null;
DiskTO rootDisk = null;
for (DiskTO vol : disks) {
if (vol.getType() == Volume.Type.ROOT) {
Map<String, String> details = vol.getDetails();
boolean managed = false;
if (details != null) {
managed = Boolean.parseBoolean(details.get(DiskTO.MANAGED));
}
if (managed) {
String datastoreName = VmwareResource.getDatastoreName(details.get(DiskTO.IQN));
rootDiskDataStoreDetails = dataStoresDetails.get(datastoreName);
} else {
DataStoreTO primaryStore = vol.getData().getDataStore();
rootDiskDataStoreDetails = dataStoresDetails.get(primaryStore.getUuid());
rootDisk = vol;
}
}
}
Pair<ManagedObjectReference, DatastoreMO> rootDiskDataStoreDetails = getDatastoreThatDiskIsOn(dataStoresDetails, rootDisk);
assert (vmSpec.getMinSpeed() != null) && (rootDiskDataStoreDetails != null);
DatastoreMO dsRootVolumeIsOn = rootDiskDataStoreDetails.second();
if (dsRootVolumeIsOn == null) {
String msg = "Unable to locate datastore details of root volume";
s_logger.error(msg);
throw new Exception(msg);
}
if (rootDisk.getDetails().get(DiskTO.PROTOCOL_TYPE) != null && rootDisk.getDetails().get(DiskTO.PROTOCOL_TYPE).equalsIgnoreCase("DatastoreCluster")) {
if (diskInfoBuilder != null) {
DatastoreMO diskDatastoreMofromVM = getDataStoreWhereDiskExists(hyperHost, context, diskInfoBuilder, rootDisk, diskDatastores);
if (diskDatastoreMofromVM != null) {
String actualPoolUuid = diskDatastoreMofromVM.getCustomFieldValue(CustomFieldConstants.CLOUD_UUID);
if (!actualPoolUuid.equalsIgnoreCase(rootDisk.getData().getDataStore().getUuid())) {
dsRootVolumeIsOn = diskDatastoreMofromVM;
}
}
}
}
boolean vmFolderExists = rootDiskDataStoreDetails.second().folderExists(String.format("[%s]", rootDiskDataStoreDetails.second().getName()), vmNameOnVcenter);
String vmxFileFullPath = dsRootVolumeIsOn.searchFileInSubFolders(vmNameOnVcenter + ".vmx", false, VmwareManager.s_vmwareSearchExcludeFolder.value());
boolean vmFolderExists = dsRootVolumeIsOn.folderExists(String.format("[%s]", dsRootVolumeIsOn.getName()), vmNameOnVcenter); String vmxFileFullPath = dsRootVolumeIsOn.searchFileInSubFolders(vmNameOnVcenter + ".vmx", false, VmwareManager.s_vmwareSearchExcludeFolder.value());
if (vmFolderExists && vmxFileFullPath != null) { // VM can be registered only if .vmx is present.
registerVm(vmNameOnVcenter, dsRootVolumeIsOn);
vmMo = hyperHost.findVmOnHyperHost(vmInternalCSName);
@ -2121,13 +2118,30 @@ public class VmwareResource implements StoragePoolResource, ServerResource, Vmwa
iScsiName = details.get(DiskTO.IQN);
}
String primaryStoreUuid = primaryStore.getUuid();
// if the storage is managed, iScsiName should not be null
String datastoreName = managed ? VmwareResource.getDatastoreName(iScsiName) : primaryStore.getUuid();
String datastoreName = managed ? VmwareResource.getDatastoreName(iScsiName) : primaryStoreUuid;
Pair<ManagedObjectReference, DatastoreMO> volumeDsDetails = dataStoresDetails.get(datastoreName);
assert (volumeDsDetails != null);
if (volumeDsDetails == null) {
throw new Exception("Primary datastore " + primaryStore.getUuid() + " is not mounted on host.");
}
String[] diskChain = syncDiskChain(dcMo, vmMo, vmSpec, vol, matchingExistingDisk, dataStoresDetails);
if (vol.getDetails().get(DiskTO.PROTOCOL_TYPE) != null && vol.getDetails().get(DiskTO.PROTOCOL_TYPE).equalsIgnoreCase("DatastoreCluster")) {
if (diskInfoBuilder != null && matchingExistingDisk == null) {
DatastoreMO diskDatastoreMofromVM = getDataStoreWhereDiskExists(hyperHost, context, diskInfoBuilder, vol, diskDatastores);
if (diskDatastoreMofromVM != null) {
String actualPoolUuid = diskDatastoreMofromVM.getCustomFieldValue(CustomFieldConstants.CLOUD_UUID);
if (!actualPoolUuid.equalsIgnoreCase(primaryStore.getUuid())) {
volumeDsDetails = new Pair<>(diskDatastoreMofromVM.getMor(), diskDatastoreMofromVM);
((PrimaryDataStoreTO)primaryStore).setUuid(actualPoolUuid);
}
}
}
}
String[] diskChain = syncDiskChain(dcMo, vmMo, vol, matchingExistingDisk, volumeDsDetails.second());
int deviceNumber = -1;
if (controllerKey == vmMo.getIDEControllerKey(ideUnitNumber)) {
@ -2872,31 +2886,18 @@ public class VmwareResource implements StoragePoolResource, ServerResource, Vmwa
}
// return the finalized disk chain for startup, from top to bottom
private String[] syncDiskChain(DatacenterMO dcMo, VirtualMachineMO vmMo, VirtualMachineTO vmSpec, DiskTO vol, VirtualMachineDiskInfo diskInfo,
HashMap<String, Pair<ManagedObjectReference, DatastoreMO>> dataStoresDetails) throws Exception {
private String[] syncDiskChain(DatacenterMO dcMo, VirtualMachineMO vmMo, DiskTO vol, VirtualMachineDiskInfo diskInfo,
DatastoreMO dsMo) throws Exception {
VolumeObjectTO volumeTO = (VolumeObjectTO) vol.getData();
DataStoreTO primaryStore = volumeTO.getDataStore();
Map<String, String> details = vol.getDetails();
boolean isManaged = false;
String iScsiName = null;
if (details != null) {
isManaged = Boolean.parseBoolean(details.get(DiskTO.MANAGED));
iScsiName = details.get(DiskTO.IQN);
}
// if the storage is managed, iScsiName should not be null
String datastoreName = isManaged ? VmwareResource.getDatastoreName(iScsiName) : primaryStore.getUuid();
Pair<ManagedObjectReference, DatastoreMO> volumeDsDetails = dataStoresDetails.get(datastoreName);
if (volumeDsDetails == null) {
throw new Exception("Primary datastore " + primaryStore.getUuid() + " is not mounted on host.");
}
DatastoreMO dsMo = volumeDsDetails.second();
String datastoreDiskPath;
if (dsMo.getDatastoreType().equalsIgnoreCase("VVOL")) {
datastoreDiskPath = VmwareStorageLayoutHelper.getLegacyDatastorePathFromVmdkFileName(dsMo, volumeTO.getPath() + ".vmdk");
if (!dsMo.fileExists(datastoreDiskPath)) {
@ -3327,6 +3328,8 @@ public class VmwareResource implements StoragePoolResource, ServerResource, Vmwa
volInSpec.setPath(datastoreVolumePath);
} else {
volInSpec.setPath(file.getFileBaseName());
if (!file.getDatastoreName().equals(volumeTO.getDataStore().getUuid()))
volInSpec.setUpdatedDataStoreUUID(file.getDatastoreName());
}
volInSpec.setChainInfo(_gson.toJson(diskInfo));
}
@ -3462,6 +3465,41 @@ public class VmwareResource implements StoragePoolResource, ServerResource, Vmwa
return path.substring(0, endIndex).trim();
}
private DatastoreMO getDataStoreWhereDiskExists(VmwareHypervisorHost hyperHost, VmwareContext context,
VirtualMachineDiskInfoBuilder diskInfoBuilder, DiskTO disk, List<Pair<Integer, ManagedObjectReference>> diskDatastores) throws Exception {
VolumeObjectTO volume = (VolumeObjectTO) disk.getData();
String diskBackingFileBaseName = volume.getPath();
for (Pair<Integer, ManagedObjectReference> diskDatastore : diskDatastores) {
DatastoreMO dsMo = new DatastoreMO(hyperHost.getContext(), diskDatastore.second());
String dsName = dsMo.getName();
VirtualMachineDiskInfo diskInfo = diskInfoBuilder.getDiskInfoByBackingFileBaseName(diskBackingFileBaseName, dsName);
if (diskInfo != null) {
s_logger.info("Found existing disk info from volume path: " + volume.getPath());
return dsMo;
} else {
String chainInfo = volume.getChainInfo();
if (chainInfo != null) {
VirtualMachineDiskInfo infoInChain = _gson.fromJson(chainInfo, VirtualMachineDiskInfo.class);
if (infoInChain != null) {
String[] disks = infoInChain.getDiskChain();
if (disks.length > 0) {
for (String diskPath : disks) {
DatastoreFile file = new DatastoreFile(diskPath);
diskInfo = diskInfoBuilder.getDiskInfoByBackingFileBaseName(file.getFileBaseName(), dsName);
if (diskInfo != null) {
s_logger.info("Found existing disk from chain info: " + diskPath);
return dsMo;
}
}
}
}
}
}
}
return null;
}
private HashMap<String, Pair<ManagedObjectReference, DatastoreMO>> inferDatastoreDetailsFromDiskInfo(VmwareHypervisorHost hyperHost, VmwareContext context,
DiskTO[] disks, Command cmd) throws Exception {
HashMap<String, Pair<ManagedObjectReference, DatastoreMO>> mapIdToMors = new HashMap<>();
@ -3534,11 +3572,9 @@ public class VmwareResource implements StoragePoolResource, ServerResource, Vmwa
return mapIdToMors;
}
private DatastoreMO getDatastoreThatRootDiskIsOn(HashMap<String, Pair<ManagedObjectReference, DatastoreMO>> dataStoresDetails, DiskTO disks[]) {
private Pair<ManagedObjectReference, DatastoreMO> getDatastoreThatDiskIsOn(HashMap<String, Pair<ManagedObjectReference, DatastoreMO>> dataStoresDetails, DiskTO vol) {
Pair<ManagedObjectReference, DatastoreMO> rootDiskDataStoreDetails = null;
for (DiskTO vol : disks) {
if (vol.getType() == Volume.Type.ROOT) {
Map<String, String> details = vol.getDetails();
boolean managed = false;
@ -3548,25 +3584,13 @@ public class VmwareResource implements StoragePoolResource, ServerResource, Vmwa
if (managed) {
String datastoreName = VmwareResource.getDatastoreName(details.get(DiskTO.IQN));
rootDiskDataStoreDetails = dataStoresDetails.get(datastoreName);
break;
} else {
DataStoreTO primaryStore = vol.getData().getDataStore();
rootDiskDataStoreDetails = dataStoresDetails.get(primaryStore.getUuid());
break;
}
}
}
if (rootDiskDataStoreDetails != null) {
return rootDiskDataStoreDetails.second();
}
return null;
return rootDiskDataStoreDetails;
}
private String getPvlanInfo(NicTO nicTo) {

View File

@ -35,6 +35,7 @@ import java.util.concurrent.Executors;
import java.util.concurrent.TimeUnit;
import com.cloud.hypervisor.vmware.mo.VirtualStorageObjectManagerMO;
import com.cloud.hypervisor.vmware.mo.VirtualMachineDiskInfoBuilder;
import com.vmware.vim25.BaseConfigInfoDiskFileBackingInfo;
import com.vmware.vim25.VStorageObject;
import com.vmware.vim25.VirtualDiskType;
@ -2081,6 +2082,7 @@ public class VmwareStorageProcessor implements StorageProcessor {
DatastoreMO dsMo = new DatastoreMO(context, morDs);
String datastoreVolumePath;
boolean datastoreChangeObserved = false;
if (isAttach) {
if (isManaged) {
@ -2106,6 +2108,25 @@ public class VmwareStorageProcessor implements StorageProcessor {
if (isManaged) {
datastoreVolumePath = dsMo.getDatastorePath((vmdkPath != null ? vmdkPath : dsMo.getName()) + ".vmdk");
} else {
String datastoreUUID = primaryStore.getUuid();
if (disk.getDetails().get(DiskTO.PROTOCOL_TYPE) != null && disk.getDetails().get(DiskTO.PROTOCOL_TYPE).equalsIgnoreCase("DatastoreCluster")) {
DatastoreMO diskDatastoreMoFromVM = getDiskDatastoreMofromVM(hyperHost, context, vmMo, disk);
if (diskDatastoreMoFromVM != null) {
String actualPoolUuid = diskDatastoreMoFromVM.getCustomFieldValue(CustomFieldConstants.CLOUD_UUID);
if (!actualPoolUuid.equalsIgnoreCase(primaryStore.getUuid())) {
s_logger.warn(String.format("Volume %s found to be in a different storage pool %s", volumeTO.getPath(), actualPoolUuid));
datastoreChangeObserved = true;
datastoreUUID = actualPoolUuid;
}
}
}
if (storagePort == DEFAULT_NFS_PORT) {
morDs = HypervisorHostHelper.findDatastoreWithBackwardsCompatibility(hyperHost, isManaged ? VmwareResource.getDatastoreName(diskUuid) : datastoreUUID);
} else {
morDs = HypervisorHostHelper.findDatastoreWithBackwardsCompatibility(hyperHost, isManaged ? VmwareResource.getDatastoreName(iScsiName) : datastoreUUID);
}
dsMo = new DatastoreMO(context, morDs);
datastoreVolumePath = VmwareStorageLayoutHelper.getLegacyDatastorePathFromVmdkFileName(dsMo, volumeTO.getPath() + ".vmdk");
if (!dsMo.fileExists(datastoreVolumePath)) {
datastoreVolumePath = VmwareStorageLayoutHelper.getVmwareDatastorePathFromVmdkFileName(dsMo, vmName, volumeTO.getPath() + ".vmdk");
@ -2147,6 +2168,8 @@ public class VmwareStorageProcessor implements StorageProcessor {
VmwareStorageLayoutHelper.syncVolumeToRootFolder(dsMo.getOwnerDatacenter().first(), dsMo, volumeTO.getPath(), vmName, VmwareManager.s_vmwareSearchExcludeFolder.value());
}
}
if (datastoreChangeObserved)
answer.setContextParam("datastoreName", dsMo.getName());
}
return answer;
@ -2172,6 +2195,44 @@ public class VmwareStorageProcessor implements StorageProcessor {
}
}
private DatastoreMO getDiskDatastoreMofromVM(VmwareHypervisorHost hyperHost, VmwareContext context,
VirtualMachineMO vmMo, DiskTO disk) throws Exception {
assert (hyperHost != null) && (context != null);
List<Pair<Integer, ManagedObjectReference>> diskDatastores = vmMo.getAllDiskDatastores();
VirtualMachineDiskInfoBuilder diskInfoBuilder = vmMo.getDiskInfoBuilder();
VolumeObjectTO volume = (VolumeObjectTO) disk.getData();
String diskBackingFileBaseName = volume.getPath();
for (Pair<Integer, ManagedObjectReference> diskDatastore : diskDatastores) {
DatastoreMO dsMo = new DatastoreMO(hyperHost.getContext(), diskDatastore.second());
String dsName = dsMo.getName();
VirtualMachineDiskInfo diskInfo = diskInfoBuilder.getDiskInfoByBackingFileBaseName(diskBackingFileBaseName, dsName);
if (diskInfo != null) {
s_logger.info("Found existing disk info from volume path: " + volume.getPath());
return dsMo;
} else {
String chainInfo = volume.getChainInfo();
if (chainInfo != null) {
VirtualMachineDiskInfo infoInChain = _gson.fromJson(chainInfo, VirtualMachineDiskInfo.class);
if (infoInChain != null) {
String[] disks = infoInChain.getDiskChain();
if (disks.length > 0) {
for (String diskPath : disks) {
DatastoreFile file = new DatastoreFile(diskPath);
diskInfo = diskInfoBuilder.getDiskInfoByBackingFileBaseName(file.getFileBaseName(), dsName);
if (diskInfo != null) {
s_logger.info("Found existing disk from chain info: " + diskPath);
return dsMo;
}
}
}
}
}
}
}
return null;
}
private boolean expandVirtualDisk(VirtualMachineMO vmMo, String datastoreVolumePath, long currentSizeInBytes) throws Exception {
long currentSizeInKB = currentSizeInBytes / 1024;

View File

@ -2025,6 +2025,14 @@ public class VolumeApiServiceImpl extends ManagerBase implements VolumeApiServic
DataTO volTO = volFactory.getVolume(volume.getId()).getTO();
DiskTO disk = new DiskTO(volTO, volume.getDeviceId(), volume.getPath(), volume.getVolumeType());
Map<String, String> details = new HashMap<String, String>();
disk.setDetails(details);
if (volume.getPoolId() != null) {
StoragePoolVO poolVO = _storagePoolDao.findById(volume.getPoolId());
if (poolVO.getParent() != 0L) {
details.put(DiskTO.PROTOCOL_TYPE, Storage.StoragePoolType.DatastoreCluster.toString());
}
}
DettachCommand cmd = new DettachCommand(disk, vm.getInstanceName());
@ -2045,6 +2053,17 @@ public class VolumeApiServiceImpl extends ManagerBase implements VolumeApiServic
if (!sendCommand || (answer != null && answer.getResult())) {
// Mark the volume as detached
_volsDao.detachVolume(volume.getId());
String datastoreName = answer.getContextParam("datastoreName");
if (datastoreName != null) {
List<StoragePoolVO> storagePoolVOS = _storagePoolDao.listPoolsByLikePath(datastoreName);
if (storagePoolVOS != null && !storagePoolVOS.isEmpty()) {
VolumeVO volumeVO = _volsDao.findById(volumeId);
volumeVO.setPoolId(storagePoolVOS.get(0).getId());
_volsDao.update(volumeVO.getId(), volumeVO);
} else {
s_logger.warn(String.format("Unable to find datastore %s while updating the new datastore of the volume %d", datastoreName, volumeId));
}
}
// volume.getPoolId() should be null if the VM we are detaching the disk from has never been started before
if (volume.getPoolId() != null) {
@ -3041,6 +3060,14 @@ public class VolumeApiServiceImpl extends ManagerBase implements VolumeApiServic
details.put(DiskTO.CHAP_TARGET_USERNAME, chapInfo.getTargetUsername());
details.put(DiskTO.CHAP_TARGET_SECRET, chapInfo.getTargetSecret());
}
if (volumeToAttach.getPoolId() != null) {
StoragePoolVO poolVO = _storagePoolDao.findById(volumeToAttach.getPoolId());
if (poolVO.getParent() != 0L) {
details.put(DiskTO.PROTOCOL_TYPE, Storage.StoragePoolType.DatastoreCluster.toString());
}
}
_userVmDao.loadDetails(vm);
Map<String, String> controllerInfo = new HashMap<String, String>();
controllerInfo.put(VmDetailConstants.ROOT_DISK_CONTROLLER, vm.getDetail(VmDetailConstants.ROOT_DISK_CONTROLLER));

View File

@ -2637,7 +2637,7 @@ public class VirtualMachineMO extends BaseMO {
VirtualDeviceBackingInfo backingInfo = ((VirtualDisk)device).getBacking();
if (backingInfo instanceof VirtualDiskFlatVer2BackingInfo) {
VirtualDiskFlatVer2BackingInfo diskBackingInfo = (VirtualDiskFlatVer2BackingInfo)backingInfo;
disks.add(new Pair<Integer, ManagedObjectReference>(new Integer(device.getKey()), diskBackingInfo.getDatastore()));
disks.add(new Pair<Integer, ManagedObjectReference>(new Integer(device.getUnitNumber()), diskBackingInfo.getDatastore()));
}
}
}