133
133
import com .cloud .dc .DataCenter ;
134
134
import com .cloud .dc .DataCenterVO ;
135
135
import com .cloud .dc .Pod ;
136
- import com .cloud .dc .dao .ClusterDao ;
137
136
import com .cloud .dc .dao .DataCenterDao ;
138
- import com .cloud .dc .dao .HostPodDao ;
139
137
import com .cloud .domain .Domain ;
140
138
import com .cloud .domain .dao .DomainDao ;
141
139
import com .cloud .event .ActionEvent ;
155
153
import com .cloud .hypervisor .HypervisorCapabilitiesVO ;
156
154
import com .cloud .hypervisor .dao .HypervisorCapabilitiesDao ;
157
155
import com .cloud .offering .DiskOffering ;
158
- import com .cloud .org .Cluster ;
159
156
import com .cloud .org .Grouping ;
160
157
import com .cloud .projects .Project ;
161
158
import com .cloud .projects .ProjectManager ;
@@ -326,8 +323,6 @@ public class VolumeApiServiceImpl extends ManagerBase implements VolumeApiServic
326
323
@ Inject
327
324
private VmWorkJobDao _workJobDao ;
328
325
@ Inject
329
- ClusterDao clusterDao ;
330
- @ Inject
331
326
private ClusterDetailsDao _clusterDetailsDao ;
332
327
@ Inject
333
328
private StorageManager storageMgr ;
@@ -351,8 +346,6 @@ public class VolumeApiServiceImpl extends ManagerBase implements VolumeApiServic
351
346
protected ProjectManager projectManager ;
352
347
@ Inject
353
348
protected StoragePoolDetailsDao storagePoolDetailsDao ;
354
- @ Inject
355
- HostPodDao podDao ;
356
349
357
350
358
351
protected Gson _gson ;
@@ -2387,18 +2380,25 @@ public Volume attachVolumeToVM(AttachVolumeCmd command) {
2387
2380
return attachVolumeToVM (command .getVirtualMachineId (), command .getId (), command .getDeviceId ());
2388
2381
}
2389
2382
2390
- protected VolumeVO getVmExistingVolumeForVolumeAttach (UserVmVO vm , VolumeInfo volumeToAttach ) {
2383
+ private Volume orchestrateAttachVolumeToVM (Long vmId , Long volumeId , Long deviceId ) {
2384
+ VolumeInfo volumeToAttach = volFactory .getVolume (volumeId );
2385
+
2386
+ if (volumeToAttach .isAttachedVM ()) {
2387
+ throw new CloudRuntimeException ("This volume is already attached to a VM." );
2388
+ }
2389
+
2390
+ UserVmVO vm = _userVmDao .findById (vmId );
2391
2391
VolumeVO existingVolumeOfVm = null ;
2392
2392
VMTemplateVO template = _templateDao .findById (vm .getTemplateId ());
2393
- List <VolumeVO > rootVolumesOfVm = _volsDao .findByInstanceAndType (vm . getId () , Volume .Type .ROOT );
2393
+ List <VolumeVO > rootVolumesOfVm = _volsDao .findByInstanceAndType (vmId , Volume .Type .ROOT );
2394
2394
if (rootVolumesOfVm .size () > 1 && template != null && !template .isDeployAsIs ()) {
2395
2395
throw new CloudRuntimeException ("The VM " + vm .getHostName () + " has more than one ROOT volume and is in an invalid state." );
2396
2396
} else {
2397
2397
if (!rootVolumesOfVm .isEmpty ()) {
2398
2398
existingVolumeOfVm = rootVolumesOfVm .get (0 );
2399
2399
} else {
2400
2400
// locate data volume of the vm
2401
- List <VolumeVO > diskVolumesOfVm = _volsDao .findByInstanceAndType (vm . getId () , Volume .Type .DATADISK );
2401
+ List <VolumeVO > diskVolumesOfVm = _volsDao .findByInstanceAndType (vmId , Volume .Type .DATADISK );
2402
2402
for (VolumeVO diskVolume : diskVolumesOfVm ) {
2403
2403
if (diskVolume .getState () != Volume .State .Allocated ) {
2404
2404
existingVolumeOfVm = diskVolume ;
@@ -2407,89 +2407,45 @@ protected VolumeVO getVmExistingVolumeForVolumeAttach(UserVmVO vm, VolumeInfo vo
2407
2407
}
2408
2408
}
2409
2409
}
2410
- if (existingVolumeOfVm == null ) {
2411
- if (s_logger .isTraceEnabled ()) {
2412
- s_logger .trace (String .format ("No existing volume found for VM (%s/%s) to attach volume %s/%s" ,
2410
+ if (s_logger .isTraceEnabled ()) {
2411
+ String msg = "attaching volume %s/%s to a VM (%s/%s) with an existing volume %s/%s on primary storage %s" ;
2412
+ if (existingVolumeOfVm != null ) {
2413
+ s_logger .trace (String .format (msg ,
2414
+ volumeToAttach .getName (), volumeToAttach .getUuid (),
2413
2415
vm .getName (), vm .getUuid (),
2414
- volumeToAttach .getName (), volumeToAttach .getUuid ()));
2416
+ existingVolumeOfVm .getName (), existingVolumeOfVm .getUuid (),
2417
+ existingVolumeOfVm .getPoolId ()));
2415
2418
}
2416
- return null ;
2417
2419
}
2418
- if (s_logger .isTraceEnabled ()) {
2419
- String msg = "attaching volume %s/%s to a VM (%s/%s) with an existing volume %s/%s on primary storage %s" ;
2420
- s_logger .trace (String .format (msg ,
2421
- volumeToAttach .getName (), volumeToAttach .getUuid (),
2422
- vm .getName (), vm .getUuid (),
2423
- existingVolumeOfVm .getName (), existingVolumeOfVm .getUuid (),
2424
- existingVolumeOfVm .getPoolId ()));
2425
- }
2426
- return existingVolumeOfVm ;
2427
- }
2428
-
2429
- protected StoragePool getPoolForAllocatedOrUploadedVolumeForAttach (final VolumeInfo volumeToAttach , final UserVmVO vm ) {
2430
- DataCenter zone = _dcDao .findById (vm .getDataCenterId ());
2431
- Pair <Long , Long > clusterHostId = virtualMachineManager .findClusterAndHostIdForVm (vm , false );
2432
- long podId = vm .getPodIdToDeployIn ();
2433
- if (clusterHostId .first () != null ) {
2434
- Cluster cluster = clusterDao .findById (clusterHostId .first ());
2435
- podId = cluster .getPodId ();
2436
- }
2437
- Pod pod = podDao .findById (podId );
2438
- DiskOfferingVO offering = _diskOfferingDao .findById (volumeToAttach .getDiskOfferingId ());
2439
- DiskProfile diskProfile = new DiskProfile (volumeToAttach .getId (), volumeToAttach .getVolumeType (),
2440
- volumeToAttach .getName (), volumeToAttach .getId (), volumeToAttach .getSize (), offering .getTagsArray (),
2441
- offering .isUseLocalStorage (), offering .isRecreatable (),
2442
- volumeToAttach .getTemplateId ());
2443
- diskProfile .setHyperType (vm .getHypervisorType ());
2444
- StoragePool pool = _volumeMgr .findStoragePool (diskProfile , zone , pod , clusterHostId .first (),
2445
- clusterHostId .second (), vm , Collections .emptySet ());
2446
- if (pool == null ) {
2447
- throw new CloudRuntimeException (String .format ("Failed to find a primary storage for volume in state: %s" , volumeToAttach .getState ()));
2448
- }
2449
- return pool ;
2450
- }
2451
-
2452
- protected VolumeInfo createVolumeOnPrimaryForAttachIfNeeded (final VolumeInfo volumeToAttach , final UserVmVO vm , VolumeVO existingVolumeOfVm ) {
2420
+
2421
+ HypervisorType rootDiskHyperType = vm .getHypervisorType ();
2422
+ HypervisorType volumeToAttachHyperType = _volsDao .getHypervisorType (volumeToAttach .getId ());
2423
+
2453
2424
VolumeInfo newVolumeOnPrimaryStorage = volumeToAttach ;
2454
- boolean volumeOnSecondary = volumeToAttach .getState () == Volume .State .Uploaded ;
2455
- if (!Arrays .asList (Volume .State .Allocated , Volume .State .Uploaded ).contains (volumeToAttach .getState ())) {
2456
- return newVolumeOnPrimaryStorage ;
2457
- }
2425
+
2458
2426
//don't create volume on primary storage if its being attached to the vm which Root's volume hasn't been created yet
2459
- StoragePool destPrimaryStorage = null ;
2427
+ StoragePoolVO destPrimaryStorage = null ;
2460
2428
if (existingVolumeOfVm != null && !existingVolumeOfVm .getState ().equals (Volume .State .Allocated )) {
2461
2429
destPrimaryStorage = _storagePoolDao .findById (existingVolumeOfVm .getPoolId ());
2462
2430
if (s_logger .isTraceEnabled () && destPrimaryStorage != null ) {
2463
2431
s_logger .trace (String .format ("decided on target storage: %s/%s" , destPrimaryStorage .getName (), destPrimaryStorage .getUuid ()));
2464
2432
}
2465
2433
}
2466
- if (destPrimaryStorage == null ) {
2467
- destPrimaryStorage = getPoolForAllocatedOrUploadedVolumeForAttach (volumeToAttach , vm );
2468
- }
2469
- try {
2470
- if (volumeOnSecondary && Storage .StoragePoolType .PowerFlex .equals (destPrimaryStorage .getPoolType ())) {
2471
- throw new InvalidParameterValueException ("Cannot attach uploaded volume, this operation is unsupported on storage pool type " + destPrimaryStorage .getPoolType ());
2472
- }
2473
- newVolumeOnPrimaryStorage = _volumeMgr .createVolumeOnPrimaryStorage (vm , volumeToAttach ,
2474
- vm .getHypervisorType (), destPrimaryStorage );
2475
- } catch (NoTransitionException e ) {
2476
- s_logger .debug ("Failed to create volume on primary storage" , e );
2477
- throw new CloudRuntimeException ("Failed to create volume on primary storage" , e );
2478
- }
2479
- return newVolumeOnPrimaryStorage ;
2480
- }
2481
2434
2482
- private Volume orchestrateAttachVolumeToVM (Long vmId , Long volumeId , Long deviceId ) {
2483
- VolumeInfo volumeToAttach = volFactory .getVolume (volumeId );
2435
+ boolean volumeOnSecondary = volumeToAttach .getState () == Volume .State .Uploaded ;
2484
2436
2485
- if (volumeToAttach .isAttachedVM ()) {
2486
- throw new CloudRuntimeException ("This volume is already attached to a VM." );
2437
+ if (destPrimaryStorage != null && (volumeToAttach .getState () == Volume .State .Allocated || volumeOnSecondary )) {
2438
+ try {
2439
+ if (volumeOnSecondary && destPrimaryStorage .getPoolType () == Storage .StoragePoolType .PowerFlex ) {
2440
+ throw new InvalidParameterValueException ("Cannot attach uploaded volume, this operation is unsupported on storage pool type " + destPrimaryStorage .getPoolType ());
2441
+ }
2442
+ newVolumeOnPrimaryStorage = _volumeMgr .createVolumeOnPrimaryStorage (vm , volumeToAttach , rootDiskHyperType , destPrimaryStorage );
2443
+ } catch (NoTransitionException e ) {
2444
+ s_logger .debug ("Failed to create volume on primary storage" , e );
2445
+ throw new CloudRuntimeException ("Failed to create volume on primary storage" , e );
2446
+ }
2487
2447
}
2488
2448
2489
- UserVmVO vm = _userVmDao .findById (vmId );
2490
- VolumeVO existingVolumeOfVm = getVmExistingVolumeForVolumeAttach (vm , volumeToAttach );
2491
- VolumeInfo newVolumeOnPrimaryStorage = createVolumeOnPrimaryForAttachIfNeeded (volumeToAttach , vm , existingVolumeOfVm );
2492
-
2493
2449
// reload the volume from db
2494
2450
newVolumeOnPrimaryStorage = volFactory .getVolume (newVolumeOnPrimaryStorage .getId ());
2495
2451
boolean moveVolumeNeeded = needMoveVolume (existingVolumeOfVm , newVolumeOnPrimaryStorage );
@@ -2507,17 +2463,19 @@ private Volume orchestrateAttachVolumeToVM(Long vmId, Long volumeId, Long device
2507
2463
StoragePoolVO vmRootVolumePool = _storagePoolDao .findById (existingVolumeOfVm .getPoolId ());
2508
2464
2509
2465
try {
2510
- HypervisorType volumeToAttachHyperType = _volsDao .getHypervisorType (volumeToAttach .getId ());
2511
2466
newVolumeOnPrimaryStorage = _volumeMgr .moveVolume (newVolumeOnPrimaryStorage , vmRootVolumePool .getDataCenterId (), vmRootVolumePool .getPodId (), vmRootVolumePool .getClusterId (),
2512
2467
volumeToAttachHyperType );
2513
- } catch (ConcurrentOperationException | StorageUnavailableException e ) {
2468
+ } catch (ConcurrentOperationException e ) {
2469
+ s_logger .debug ("move volume failed" , e );
2470
+ throw new CloudRuntimeException ("move volume failed" , e );
2471
+ } catch (StorageUnavailableException e ) {
2514
2472
s_logger .debug ("move volume failed" , e );
2515
2473
throw new CloudRuntimeException ("move volume failed" , e );
2516
2474
}
2517
2475
}
2518
2476
VolumeVO newVol = _volsDao .findById (newVolumeOnPrimaryStorage .getId ());
2519
2477
// Getting the fresh vm object in case of volume migration to check the current state of VM
2520
- if (moveVolumeNeeded ) {
2478
+ if (moveVolumeNeeded || volumeOnSecondary ) {
2521
2479
vm = _userVmDao .findById (vmId );
2522
2480
if (vm == null ) {
2523
2481
throw new InvalidParameterValueException ("VM not found." );
@@ -2701,6 +2659,9 @@ private void checkDeviceId(Long deviceId, VolumeInfo volumeToAttach, UserVmVO vm
2701
2659
if (!_volsDao .findByInstanceAndDeviceId (vm .getId (), 0 ).isEmpty ()) {
2702
2660
throw new InvalidParameterValueException ("Vm already has root volume attached to it" );
2703
2661
}
2662
+ if (volumeToAttach .getState () == Volume .State .Uploaded ) {
2663
+ throw new InvalidParameterValueException ("No support for Root volume attach in state " + Volume .State .Uploaded );
2664
+ }
2704
2665
}
2705
2666
}
2706
2667
0 commit comments