Updated Branches: refs/heads/4.3 151c23981 -> e2364cfca
CLOUDSTACK-5873: [Automation] Failed to attach volume to VM, if the vm is created with option startvm=false Project: http://git-wip-us.apache.org/repos/asf/cloudstack/repo Commit: http://git-wip-us.apache.org/repos/asf/cloudstack/commit/e2364cfc Tree: http://git-wip-us.apache.org/repos/asf/cloudstack/tree/e2364cfc Diff: http://git-wip-us.apache.org/repos/asf/cloudstack/diff/e2364cfc Branch: refs/heads/4.3 Commit: e2364cfca6aa9f4c33d98fa8d2b2461d996b1ddd Parents: 151c239 Author: Mike Tutkowski <mike.tutkow...@solidfire.com> Authored: Wed Jan 15 14:33:15 2014 -0700 Committer: Mike Tutkowski <mike.tutkow...@solidfire.com> Committed: Thu Jan 16 12:08:05 2014 -0700 ---------------------------------------------------------------------- .../com/cloud/vm/VirtualMachineManagerImpl.java | 8 ++- .../orchestration/VolumeOrchestrator.java | 19 ++++++ .../xen/resource/CitrixResourceBase.java | 63 +++++++++++++++++++- .../xen/resource/XenServerStorageProcessor.java | 16 +---- 4 files changed, 86 insertions(+), 20 deletions(-) ---------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/cloudstack/blob/e2364cfc/engine/orchestration/src/com/cloud/vm/VirtualMachineManagerImpl.java ---------------------------------------------------------------------- diff --git a/engine/orchestration/src/com/cloud/vm/VirtualMachineManagerImpl.java b/engine/orchestration/src/com/cloud/vm/VirtualMachineManagerImpl.java index af65ac6..e90ff1f 100755 --- a/engine/orchestration/src/com/cloud/vm/VirtualMachineManagerImpl.java +++ b/engine/orchestration/src/com/cloud/vm/VirtualMachineManagerImpl.java @@ -1123,15 +1123,17 @@ public class VirtualMachineManagerImpl extends ManagerBase implements VirtualMac Map<String, String> details = disk.getDetails(); boolean isManaged = details != null && Boolean.parseBoolean(details.get(DiskTO.MANAGED)); - if (isManaged && disk.getPath() == null) { + if (isManaged) { Long volumeId = disk.getData().getId(); VolumeVO volume = _volsDao.findById(volumeId); String iScsiName = volume.get_iScsiName(); String path = iqnToPath.get(iScsiName); - volume.setPath(path); + if (path != null) { + volume.setPath(path); - _volsDao.update(volumeId, volume); + _volsDao.update(volumeId, volume); + } } } } http://git-wip-us.apache.org/repos/asf/cloudstack/blob/e2364cfc/engine/orchestration/src/org/apache/cloudstack/engine/orchestration/VolumeOrchestrator.java ---------------------------------------------------------------------- diff --git a/engine/orchestration/src/org/apache/cloudstack/engine/orchestration/VolumeOrchestrator.java b/engine/orchestration/src/org/apache/cloudstack/engine/orchestration/VolumeOrchestrator.java index 268b317..edc5985 100644 --- a/engine/orchestration/src/org/apache/cloudstack/engine/orchestration/VolumeOrchestrator.java +++ b/engine/orchestration/src/org/apache/cloudstack/engine/orchestration/VolumeOrchestrator.java @@ -438,6 +438,7 @@ public class VolumeOrchestrator extends ManagerBase implements VolumeOrchestrati @DB public VolumeInfo createVolume(VolumeInfo volume, VirtualMachine vm, VirtualMachineTemplate template, DataCenter dc, Pod pod, Long clusterId, ServiceOffering offering, DiskOffering diskOffering, List<StoragePool> avoids, long size, HypervisorType hyperType) { + // update the volume's hypervisor_ss_reserve from its disk offering (used for managed storage) volume = updateHypervisorSnapshotReserveForVolume(diskOffering, volume, hyperType); StoragePool pool = null; @@ -1156,6 +1157,14 @@ public class VolumeOrchestrator extends ManagerBase implements VolumeOrchestrati // retry one more time in case of template reload is required for Vmware case AsyncCallFuture<VolumeApiResult> future = null; if (templateId == null) { + DiskOffering diskOffering = _entityMgr.findById(DiskOffering.class, volume.getDiskOfferingId()); + HypervisorType hyperType = vm.getVirtualMachine().getHypervisorType(); + + // update the volume's hypervisor_ss_reserve from its disk offering (used for managed storage) + updateHypervisorSnapshotReserveForVolume(diskOffering, volume, hyperType); + + volume = volFactory.getVolume(newVol.getId(), destPool); + future = volService.createVolumeAsync(volume, destPool); } else { TemplateInfo templ = tmplFactory.getTemplate(templateId, DataStoreRole.Image); @@ -1174,6 +1183,16 @@ public class VolumeOrchestrator extends ManagerBase implements VolumeOrchestrati throw new StorageUnavailableException("Unable to create " + newVol + ":" + result.getResult(), destPool.getId()); } } + + StoragePoolVO storagePool = _storagePoolDao.findById(destPool.getId()); + + if (newVol.getVolumeType() == Type.DATADISK && storagePool.isManaged()) { + long hostId = vm.getVirtualMachine().getHostId(); + Host host = _hostDao.findById(hostId); + + volService.connectVolumeToHost(volFactory.getVolume(newVol.getId()), host, destPool); + } + newVol = _volsDao.findById(newVol.getId()); break; //break out of template-redeploy retry loop } catch (InterruptedException e) { http://git-wip-us.apache.org/repos/asf/cloudstack/blob/e2364cfc/plugins/hypervisors/xen/src/com/cloud/hypervisor/xen/resource/CitrixResourceBase.java ---------------------------------------------------------------------- diff --git a/plugins/hypervisors/xen/src/com/cloud/hypervisor/xen/resource/CitrixResourceBase.java b/plugins/hypervisors/xen/src/com/cloud/hypervisor/xen/resource/CitrixResourceBase.java index a23a646..aaa97bf 100644 --- a/plugins/hypervisors/xen/src/com/cloud/hypervisor/xen/resource/CitrixResourceBase.java +++ b/plugins/hypervisors/xen/src/com/cloud/hypervisor/xen/resource/CitrixResourceBase.java @@ -1192,10 +1192,12 @@ public abstract class CitrixResourceBase implements ServerResource, HypervisorRe } } - protected VBD createVbd(Connection conn, DiskTO volume, String vmName, VM vm, BootloaderType bootLoaderType) throws XmlRpcException, XenAPIException { + protected VBD createVbd(Connection conn, DiskTO volume, String vmName, VM vm, BootloaderType bootLoaderType, VDI vdi) throws XmlRpcException, XenAPIException { Volume.Type type = volume.getType(); - VDI vdi = mount(conn, vmName, volume); + if (vdi == null) { + vdi = mount(conn, vmName, volume); + } if ( vdi != null ) { if ("detached".equals(vdi.getNameLabel(conn))) { @@ -1686,7 +1688,15 @@ public abstract class CitrixResourceBase implements ServerResource, HypervisorRe vm = createVmFromTemplate(conn, vmSpec, host); for (DiskTO disk : vmSpec.getDisks()) { - createVbd(conn, disk, vmName, vm, vmSpec.getBootloader()); + VDI newVdi = prepareManagedDisk(conn, disk, vmName); + + if (newVdi != null) { + String path = newVdi.getUuid(conn); + + iqnToPath.put(disk.getDetails().get(DiskTO.IQN), path); + } + + createVbd(conn, disk, vmName, vm, vmSpec.getBootloader(), newVdi); } if (vmSpec.getType() != VirtualMachine.Type.User) { @@ -1796,6 +1806,53 @@ public abstract class CitrixResourceBase implements ServerResource, HypervisorRe } } + // the idea here is to see if the DiskTO in question is from managed storage and + // does not yet have an SR + // if no SR, create it and create a VDI in it + private VDI prepareManagedDisk(Connection conn, DiskTO disk, String vmName) throws Exception { + Map<String, String> details = disk.getDetails(); + + if (details == null) { + return null; + } + + boolean isManaged = new Boolean(details.get(DiskTO.MANAGED)).booleanValue(); + + if (!isManaged) { + return null; + } + + String iqn = details.get(DiskTO.IQN); + + Set<SR> srNameLabels = SR.getByNameLabel(conn, iqn); + + if (srNameLabels.size() != 0) { + return null; + } + + String vdiNameLabel = vmName + "-DATA"; + + return prepareManagedStorage(conn, details, null, vdiNameLabel); + } + + protected VDI prepareManagedStorage(Connection conn, Map<String, String> details, String path, String vdiNameLabel) throws Exception { + String iScsiName = details.get(DiskTO.IQN); + String storageHost = details.get(DiskTO.STORAGE_HOST); + String chapInitiatorUsername = details.get(DiskTO.CHAP_INITIATOR_USERNAME); + String chapInitiatorSecret = details.get(DiskTO.CHAP_INITIATOR_SECRET); + Long volumeSize = Long.parseLong(details.get(DiskTO.VOLUME_SIZE)); + + SR sr = getIscsiSR(conn, iScsiName, storageHost, iScsiName, chapInitiatorUsername, chapInitiatorSecret, true); + + VDI vdi = getVDIbyUuid(conn, path, false); + + if (vdi == null) { + vdi = createVdi(sr, vdiNameLabel, volumeSize); + } + + return vdi; + } + protected Answer execute(ModifySshKeysCommand cmd) { return new Answer(cmd); } http://git-wip-us.apache.org/repos/asf/cloudstack/blob/e2364cfc/plugins/hypervisors/xen/src/com/cloud/hypervisor/xen/resource/XenServerStorageProcessor.java ---------------------------------------------------------------------- diff --git a/plugins/hypervisors/xen/src/com/cloud/hypervisor/xen/resource/XenServerStorageProcessor.java b/plugins/hypervisors/xen/src/com/cloud/hypervisor/xen/resource/XenServerStorageProcessor.java index d5ef334..430dcb8 100644 --- a/plugins/hypervisors/xen/src/com/cloud/hypervisor/xen/resource/XenServerStorageProcessor.java +++ b/plugins/hypervisors/xen/src/com/cloud/hypervisor/xen/resource/XenServerStorageProcessor.java @@ -185,7 +185,7 @@ public class XenServerStorageProcessor implements StorageProcessor { catch (CloudRuntimeException ex) { } - Map<String, String> details = cmd.getDisk().getDetails(); + Map<String, String> details = disk.getDetails(); boolean isManaged = Boolean.parseBoolean(details.get(DiskTO.MANAGED)); // if the VM is not running and we're not dealing with managed storage, just return success (nothing to do here) @@ -197,19 +197,7 @@ public class XenServerStorageProcessor implements StorageProcessor { VDI vdi = null; if (isManaged) { - String iScsiName = details.get(DiskTO.IQN); - String storageHost = details.get(DiskTO.STORAGE_HOST); - String chapInitiatorUsername = disk.getDetails().get(DiskTO.CHAP_INITIATOR_USERNAME); - String chapInitiatorSecret = disk.getDetails().get(DiskTO.CHAP_INITIATOR_SECRET); - Long volumeSize = Long.parseLong(details.get(DiskTO.VOLUME_SIZE)); - - SR sr = this.hypervisorResource.getIscsiSR(conn, iScsiName, storageHost, iScsiName, chapInitiatorUsername, chapInitiatorSecret, true); - - vdi = hypervisorResource.getVDIbyUuid(conn, data.getPath(), false); - - if (vdi == null) { - vdi = hypervisorResource.createVdi(sr, vdiNameLabel, volumeSize); - } + vdi = hypervisorResource.prepareManagedStorage(conn, details, data.getPath(), vdiNameLabel); if (vmNotRunning) { DiskTO newDisk = new DiskTO(disk.getData(), disk.getDiskSeq(), vdi.getUuid(conn), disk.getType());