@@ -1433,9 +1433,9 @@ public Volume attachVolumeToVM(Long vmId, Long volumeId, Long deviceId) {
14331433 // that supported by hypervisor
14341434 if (deviceId == null || deviceId .longValue () != 0 ) {
14351435 List <VolumeVO > existingDataVolumes = _volsDao .findByInstanceAndType (vmId , Volume .Type .DATADISK );
1436- int maxDataVolumesSupported = getMaxDataVolumesSupported (vm );
1437- if (existingDataVolumes .size () >= maxDataVolumesSupported ) {
1438- throw new InvalidParameterValueException ("The specified VM already has the maximum number of data disks (" + maxDataVolumesSupported + "). Please specify another VM." );
1436+ int maxAttachableDataVolumesSupported = getMaxDataVolumesSupported (vm ) - 2 ; //IDs: 0 (ROOT) and 3 (CD-ROM) are reserved
1437+ if (existingDataVolumes .size () >= maxAttachableDataVolumesSupported ) {
1438+ throw new InvalidParameterValueException ("The specified VM already has the maximum number of data disks (" + maxAttachableDataVolumesSupported + ") attached . Please specify another VM." );
14391439 }
14401440 }
14411441
@@ -2527,7 +2527,7 @@ private VolumeVO sendAttachVolumeCommand(UserVmVO vm, VolumeVO volumeToAttach, L
25272527
25282528 DataTO volTO = volFactory .getVolume (volumeToAttach .getId ()).getTO ();
25292529
2530- deviceId = getDeviceId (vm . getId () , deviceId );
2530+ deviceId = getDeviceId (vm , deviceId );
25312531
25322532 DiskTO disk = storageMgr .getDiskWithThrottling (volTO , volumeToAttach .getVolumeType (), deviceId , volumeToAttach .getPath (),
25332533 vm .getServiceOfferingId (), volumeToAttach .getDiskOfferingId ());
@@ -2585,7 +2585,7 @@ private VolumeVO sendAttachVolumeCommand(UserVmVO vm, VolumeVO volumeToAttach, L
25852585 _volsDao .update (volumeToAttach .getId (), volumeToAttach );
25862586 }
25872587 } else {
2588- deviceId = getDeviceId (vm . getId () , deviceId );
2588+ deviceId = getDeviceId (vm , deviceId );
25892589
25902590 _volsDao .attachVolume (volumeToAttach .getId (), vm .getId (), deviceId );
25912591 }
@@ -2623,7 +2623,7 @@ private int getMaxDataVolumesSupported(UserVmVO vm) {
26232623 _hostDao .loadDetails (host );
26242624 maxDataVolumesSupported = _hypervisorCapabilitiesDao .getMaxDataVolumesLimit (host .getHypervisorType (), host .getDetail ("product_version" ));
26252625 }
2626- if (maxDataVolumesSupported == null ) {
2626+ if (maxDataVolumesSupported == null || maxDataVolumesSupported . intValue () <= 0 ) {
26272627 maxDataVolumesSupported = 6 ; // 6 data disks by default if nothing
26282628 // is specified in
26292629 // 'hypervisor_capabilities' table
@@ -2632,28 +2632,32 @@ private int getMaxDataVolumesSupported(UserVmVO vm) {
26322632 return maxDataVolumesSupported .intValue ();
26332633 }
26342634
2635- private Long getDeviceId (long vmId , Long deviceId ) {
2635+ private Long getDeviceId (UserVmVO vm , Long deviceId ) {
26362636 // allocate deviceId
2637- List <VolumeVO > vols = _volsDao .findByInstance (vmId );
2637+ int maxDeviceId = getMaxDataVolumesSupported (vm ) - 1 ;
2638+ List <VolumeVO > vols = _volsDao .findByInstance (vm .getId ());
26382639 if (deviceId != null ) {
2639- if (deviceId .longValue () > 15 || deviceId .longValue () == 3 ) {
2640- throw new RuntimeException ("deviceId should be 1,2,4-15" );
2640+ if (deviceId .longValue () <= 0 || deviceId . longValue () > maxDeviceId || deviceId .longValue () == 3 ) {
2641+ throw new RuntimeException ("deviceId should be 1,2,4-" + maxDeviceId );
26412642 }
26422643 for (VolumeVO vol : vols ) {
26432644 if (vol .getDeviceId ().equals (deviceId )) {
2644- throw new RuntimeException ("deviceId " + deviceId + " is used by vm" + vmId );
2645+ throw new RuntimeException ("deviceId " + deviceId + " is used by vm " + vm . getId () );
26452646 }
26462647 }
26472648 } else {
26482649 // allocate deviceId here
26492650 List <String > devIds = new ArrayList <String >();
2650- for (int i = 1 ; i < 15 ; i ++) {
2651+ for (int i = 1 ; i <= maxDeviceId ; i ++) {
26512652 devIds .add (String .valueOf (i ));
26522653 }
26532654 devIds .remove ("3" );
26542655 for (VolumeVO vol : vols ) {
26552656 devIds .remove (vol .getDeviceId ().toString ().trim ());
26562657 }
2658+ if (devIds .isEmpty ()) {
2659+ throw new RuntimeException ("All device Ids are used by vm " + vm .getId ());
2660+ }
26572661 deviceId = Long .parseLong (devIds .iterator ().next ());
26582662 }
26592663
0 commit comments