Skip to content

Commit 7e08635

Browse files
committed
bug CS-14814: Do not allow attaching volume to a stopped vm for an uploaded volume. Make changes to accomodate volume attaching for a vm created in Stopped state.
1 parent 0c26f35 commit 7e08635

File tree

1 file changed

+25
-9
lines changed

1 file changed

+25
-9
lines changed

server/src/com/cloud/vm/UserVmManagerImpl.java

Lines changed: 25 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -553,10 +553,10 @@ public Volume attachVolumeToVM(AttachVolumeCmd command) {
553553
_accountMgr.checkAccess(caller, null, true, volume, vm);
554554

555555
//Check if volume is stored on secondary Storage.
556-
boolean volumeOnSec = false;
556+
boolean isVolumeOnSec = false;
557557
VolumeHostVO volHostVO = _volumeHostDao.findByVolumeId(volume.getId());
558558
if (volHostVO != null){
559-
volumeOnSec = true;
559+
isVolumeOnSec = true;
560560
if( !(volHostVO.getDownloadState() == Status.DOWNLOADED) ){
561561
throw new InvalidParameterValueException("Volume is not uploaded yet. Please try this operation once the volume is uploaded");
562562
}
@@ -568,7 +568,7 @@ public Volume attachVolumeToVM(AttachVolumeCmd command) {
568568
}
569569

570570
if ( !(Volume.State.Allocated.equals(volume.getState()) || Volume.State.Ready.equals(volume.getState()) || Volume.State.UploadOp.equals(volume.getState())) ) {
571-
throw new InvalidParameterValueException("Volume state must be in Allocated or Ready state");
571+
throw new InvalidParameterValueException("Volume state must be in Allocated, Ready or in Uploaded state");
572572
}
573573

574574
VolumeVO rootVolumeOfVm = null;
@@ -581,8 +581,8 @@ public Volume attachVolumeToVM(AttachVolumeCmd command) {
581581

582582
HypervisorType rootDiskHyperType = _volsDao.getHypervisorType(rootVolumeOfVm.getId());
583583

584-
if (volume.getState().equals(Volume.State.Allocated) || volume.getState().equals(Volume.State.UploadOp)) {
585-
/* Need to create the volume */
584+
/*if (volume.getState().equals(Volume.State.Allocated) || volume.getState().equals(Volume.State.UploadOp)) {
585+
// Need to create the volume
586586
VMTemplateVO rootDiskTmplt = _templateDao.findById(vm.getTemplateId());
587587
DataCenterVO dcVO = _dcDao.findById(vm.getDataCenterIdToDeployIn());
588588
HostPodVO pod = _podDao.findById(vm.getPodIdToDeployIn());
@@ -607,7 +607,7 @@ public Volume attachVolumeToVM(AttachVolumeCmd command) {
607607
if (volume == null) {
608608
throw new CloudRuntimeException("Failed to create volume when attaching it to VM: " + vm.getHostName());
609609
}
610-
}
610+
}*/
611611

612612
HypervisorType dataDiskHyperType = _volsDao.getHypervisorType(volume.getId());
613613
if (dataDiskHyperType != HypervisorType.None && rootDiskHyperType != dataDiskHyperType) {
@@ -641,11 +641,14 @@ public Volume attachVolumeToVM(AttachVolumeCmd command) {
641641
boolean createVolumeOnBackend = true;
642642
if (rootVolumeOfVm.getState() == Volume.State.Allocated) {
643643
createVolumeOnBackend = false;
644+
if(isVolumeOnSec){
645+
throw new CloudRuntimeException("Cant attach uploaded volume to the vm which is not created. Please start it and then retry");
646+
}
644647
}
645648

646649
//create volume on the backend only when vm's root volume is allocated
647650
if (createVolumeOnBackend) {
648-
if (volume.getState().equals(Volume.State.Allocated)) {
651+
if (volume.getState().equals(Volume.State.Allocated) || isVolumeOnSec) {
649652
/* Need to create the volume */
650653
VMTemplateVO rootDiskTmplt = _templateDao.findById(vm.getTemplateId());
651654
DataCenterVO dcVO = _dcDao.findById(vm.getDataCenterIdToDeployIn());
@@ -654,8 +657,21 @@ public Volume attachVolumeToVM(AttachVolumeCmd command) {
654657
ServiceOfferingVO svo = _serviceOfferingDao.findById(vm.getServiceOfferingId());
655658
DiskOfferingVO diskVO = _diskOfferingDao.findById(volume.getDiskOfferingId());
656659
Long clusterId = (rootDiskPool == null ? null : rootDiskPool.getClusterId());
657-
658-
volume = _storageMgr.createVolume(volume, vm, rootDiskTmplt, dcVO, pod, clusterId, svo, diskVO, new ArrayList<StoragePoolVO>(), volume.getSize(), rootDiskHyperType);
660+
661+
if (!isVolumeOnSec){
662+
volume = _storageMgr.createVolume(volume, vm, rootDiskTmplt, dcVO, pod, clusterId, svo, diskVO, new ArrayList<StoragePoolVO>(), volume.getSize(), rootDiskHyperType);
663+
}else {
664+
try {
665+
// Format of data disk should be the same as root disk
666+
if( ! volHostVO.getFormat().getFileExtension().equals(_storageMgr.getSupportedImageFormatForCluster(rootDiskPool.getClusterId())) ){
667+
throw new InvalidParameterValueException("Failed to attach volume to VM since volumes format " +volHostVO.getFormat().getFileExtension() + " is not compatible with the vm hypervisor type" );
668+
}
669+
670+
volume = _storageMgr.copyVolumeFromSecToPrimary(volume, vm, rootDiskTmplt, dcVO, pod, rootDiskPool.getClusterId(), svo, diskVO, new ArrayList<StoragePoolVO>(), volume.getSize(), rootDiskHyperType);
671+
} catch (NoTransitionException e) {
672+
throw new CloudRuntimeException("Unable to transition the volume ",e);
673+
}
674+
}
659675

660676
if (volume == null) {
661677
throw new CloudRuntimeException("Failed to create volume when attaching it to VM: " + vm.getHostName());

0 commit comments

Comments
 (0)