Updated Branches: refs/heads/master 3ef560d92 -> e9c9887ee
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/e9c9887e Tree: http://git-wip-us.apache.org/repos/asf/cloudstack/tree/e9c9887e Diff: http://git-wip-us.apache.org/repos/asf/cloudstack/diff/e9c9887e Branch: refs/heads/master Commit: e9c9887ee03b1987c6554f63e0f9a74d74f7a023 Parents: 3ef560d Author: Mike Tutkowski <mike.tutkow...@solidfire.com> Authored: Thu Jan 16 12:20:54 2014 -0700 Committer: Mike Tutkowski <mike.tutkow...@solidfire.com> Committed: Thu Jan 16 12:20:54 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/e9c9887e/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 9894d31..806ac7e 100755 --- a/engine/orchestration/src/com/cloud/vm/VirtualMachineManagerImpl.java +++ b/engine/orchestration/src/com/cloud/vm/VirtualMachineManagerImpl.java @@ -1127,15 +1127,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/e9c9887e/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 0d6d718..8129b9d 100644 --- a/engine/orchestration/src/org/apache/cloudstack/engine/orchestration/VolumeOrchestrator.java +++ b/engine/orchestration/src/org/apache/cloudstack/engine/orchestration/VolumeOrchestrator.java @@ -408,6 +408,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; @@ -1089,6 +1090,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); @@ -1106,6 +1115,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/e9c9887e/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 accaa85..acdc70f 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 @@ -1262,10 +1262,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))) { @@ -1754,7 +1756,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) { @@ -1866,6 +1876,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/e9c9887e/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 5d2363f..f2abff7 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 = 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());