@@ -2350,13 +2350,16 @@ protected StartAnswer execute(StartCommand cmd) {
23502350 continue ;
23512351 }
23522352
2353+ VirtualMachineDiskInfo matchingExistingDisk = getMatchingExistingDisk (diskInfoBuilder , vol , hyperHost , context );
2354+ Pair <ManagedObjectReference , DatastoreMO > volumeDsDetails = getVolumeDatastoreDetails (vol , dataStoresDetails );
2355+ syncVolumeDatastoreAndPathForDatastoreCluster (vol , diskInfoBuilder , matchingExistingDisk , volumeDsDetails , diskDatastores , hyperHost , context );
2356+
23532357 if (deployAsIs && vol .getType () == Volume .Type .ROOT ) {
23542358 rootDiskTO = vol ;
23552359 resizeRootDiskOnVMStart (vmMo , rootDiskTO , hyperHost , context );
23562360 continue ;
23572361 }
23582362
2359- VirtualMachineDiskInfo matchingExistingDisk = getMatchingExistingDisk (diskInfoBuilder , vol , hyperHost , context );
23602363 String diskController = getDiskController (vmMo , matchingExistingDisk , vol , chosenDiskControllers , deployAsIs );
23612364 if (DiskControllerType .getType (diskController ) == DiskControllerType .ide ) {
23622365 controllerKey = vmMo .getIDEControllerKey (ideUnitNumber );
@@ -2365,7 +2368,7 @@ protected StartAnswer execute(StartCommand cmd) {
23652368 // Ensure maximum of 2 data volumes over IDE controller, 3 includeing root volume
23662369 if (vmMo .getNumberOfVirtualDisks () > 3 ) {
23672370 throw new CloudRuntimeException ("Found more than 3 virtual disks attached to this VM [" + vmMo .getVmName () + "]. Unable to implement the disks over "
2368- + diskController + " controller, as maximum number of devices supported over IDE controller is 4 includeing CDROM device." );
2371+ + diskController + " controller, as maximum number of devices supported over IDE controller is 4 including CDROM device." );
23692372 }
23702373 }
23712374 } else {
@@ -2385,51 +2388,6 @@ protected StartAnswer execute(StartCommand cmd) {
23852388 if (!hasSnapshot ) {
23862389 deviceConfigSpecArray [i ] = new VirtualDeviceConfigSpec ();
23872390
2388- VolumeObjectTO volumeTO = (VolumeObjectTO ) vol .getData ();
2389- DataStoreTO primaryStore = volumeTO .getDataStore ();
2390- Map <String , String > details = vol .getDetails ();
2391- boolean managed = false ;
2392- String iScsiName = null ;
2393-
2394- if (details != null ) {
2395- managed = Boolean .parseBoolean (details .get (DiskTO .MANAGED ));
2396- iScsiName = details .get (DiskTO .IQN );
2397- }
2398-
2399- String primaryStoreUuid = primaryStore .getUuid ();
2400- // if the storage is managed, iScsiName should not be null
2401- String datastoreName = managed ? VmwareResource .getDatastoreName (iScsiName ) : primaryStoreUuid ;
2402- Pair <ManagedObjectReference , DatastoreMO > volumeDsDetails = dataStoresDetails .get (datastoreName );
2403-
2404- assert (volumeDsDetails != null );
2405- if (volumeDsDetails == null ) {
2406- throw new Exception ("Primary datastore " + primaryStore .getUuid () + " is not mounted on host." );
2407- }
2408-
2409- if (vol .getDetails ().get (DiskTO .PROTOCOL_TYPE ) != null && vol .getDetails ().get (DiskTO .PROTOCOL_TYPE ).equalsIgnoreCase ("DatastoreCluster" )) {
2410- if (diskInfoBuilder != null && matchingExistingDisk != null ) {
2411- String [] diskChain = matchingExistingDisk .getDiskChain ();
2412- if (diskChain != null && diskChain .length > 0 ) {
2413- DatastoreFile file = new DatastoreFile (diskChain [0 ]);
2414- if (!file .getFileBaseName ().equalsIgnoreCase (volumeTO .getPath ())) {
2415- if (s_logger .isInfoEnabled ())
2416- s_logger .info ("Detected disk-chain top file change on volume: " + volumeTO .getId () + " " + volumeTO .getPath () + " -> " + file .getFileBaseName ());
2417- volumeTO .setPath (file .getFileBaseName ());
2418- }
2419- }
2420- DatastoreMO diskDatastoreMofromVM = getDataStoreWhereDiskExists (hyperHost , context , diskInfoBuilder , vol , diskDatastores );
2421- if (diskDatastoreMofromVM != null ) {
2422- String actualPoolUuid = diskDatastoreMofromVM .getCustomFieldValue (CustomFieldConstants .CLOUD_UUID );
2423- if (actualPoolUuid != null && !actualPoolUuid .equalsIgnoreCase (primaryStore .getUuid ())) {
2424- volumeDsDetails = new Pair <>(diskDatastoreMofromVM .getMor (), diskDatastoreMofromVM );
2425- if (s_logger .isInfoEnabled ())
2426- s_logger .info ("Detected datastore uuid change on volume: " + volumeTO .getId () + " " + primaryStore .getUuid () + " -> " + actualPoolUuid );
2427- ((PrimaryDataStoreTO )primaryStore ).setUuid (actualPoolUuid );
2428- }
2429- }
2430- }
2431- }
2432-
24332391 String [] diskChain = syncDiskChain (dcMo , vmMo , vol , matchingExistingDisk , volumeDsDetails .second ());
24342392
24352393 int deviceNumber = -1 ;
@@ -2441,6 +2399,7 @@ protected StartAnswer execute(StartCommand cmd) {
24412399 scsiUnitNumber ++;
24422400 }
24432401
2402+ VolumeObjectTO volumeTO = (VolumeObjectTO ) vol .getData ();
24442403 Long maxIops = volumeTO .getIopsWriteRate () + volumeTO .getIopsReadRate ();
24452404 VirtualDevice device = VmwareHelper .prepareDiskDevice (vmMo , null , controllerKey , diskChain , volumeDsDetails .first (), deviceNumber , i + 1 , maxIops );
24462405 s_logger .debug (LogUtils .logGsonWithoutException ("The following definitions will be used to start the VM: virtual device [%s], volume [%s]." , device , volumeTO ));
@@ -2709,6 +2668,64 @@ protected StartAnswer execute(StartCommand cmd) {
27092668 }
27102669 }
27112670
2671+ private Pair <ManagedObjectReference , DatastoreMO > getVolumeDatastoreDetails (DiskTO vol , HashMap <String , Pair <ManagedObjectReference , DatastoreMO >> dataStoresDetails ) throws Exception {
2672+ boolean managed = false ;
2673+ String iScsiName = null ;
2674+ Map <String , String > details = vol .getDetails ();
2675+ if (MapUtils .isNotEmpty (details )) {
2676+ managed = Boolean .parseBoolean (details .get (DiskTO .MANAGED ));
2677+ iScsiName = details .get (DiskTO .IQN );
2678+ }
2679+
2680+ VolumeObjectTO volumeTO = (VolumeObjectTO ) vol .getData ();
2681+ DataStoreTO primaryStore = volumeTO .getDataStore ();
2682+ String primaryStoreUuid = primaryStore .getUuid ();
2683+ // if the storage is managed, iScsiName should not be null
2684+ String datastoreName = managed ? VmwareResource .getDatastoreName (iScsiName ) : primaryStoreUuid ;
2685+ Pair <ManagedObjectReference , DatastoreMO > volumeDsDetails = dataStoresDetails .get (datastoreName );
2686+ if (volumeDsDetails == null ) {
2687+ throw new Exception ("Primary datastore " + primaryStore .getUuid () + " is not mounted on host." );
2688+ }
2689+
2690+ return volumeDsDetails ;
2691+ }
2692+
2693+ private void syncVolumeDatastoreAndPathForDatastoreCluster (DiskTO vol , VirtualMachineDiskInfoBuilder diskInfoBuilder , VirtualMachineDiskInfo matchingExistingDisk ,
2694+ Pair <ManagedObjectReference , DatastoreMO > volumeDsDetails , List <Pair <Integer , ManagedObjectReference >> diskDatastores ,
2695+ VmwareHypervisorHost hyperHost , VmwareContext context ) throws Exception {
2696+ if (vol .getDetails () == null || vol .getDetails ().get (DiskTO .PROTOCOL_TYPE ) == null || !vol .getDetails ().get (DiskTO .PROTOCOL_TYPE ).equalsIgnoreCase ("DatastoreCluster" )) {
2697+ return ;
2698+ }
2699+
2700+ if (diskInfoBuilder != null && matchingExistingDisk != null ) {
2701+ String [] diskChain = matchingExistingDisk .getDiskChain ();
2702+ if (diskChain != null && diskChain .length > 0 ) {
2703+ DatastoreFile file = new DatastoreFile (diskChain [0 ]);
2704+ VolumeObjectTO volumeTO = (VolumeObjectTO ) vol .getData ();
2705+ if (!file .getFileBaseName ().equalsIgnoreCase (volumeTO .getPath ())) {
2706+ if (s_logger .isInfoEnabled ()) {
2707+ s_logger .info ("Detected disk-chain top file change on volume: " + volumeTO .getId () + " " + volumeTO .getPath () + " -> " + file .getFileBaseName ());
2708+ }
2709+ volumeTO .setPath (file .getFileBaseName ());
2710+ vol .setPath (file .getFileBaseName ());
2711+ }
2712+ }
2713+ DatastoreMO diskDatastoreMofromVM = getDataStoreWhereDiskExists (hyperHost , context , diskInfoBuilder , vol , diskDatastores );
2714+ if (diskDatastoreMofromVM != null ) {
2715+ String actualPoolUuid = diskDatastoreMofromVM .getCustomFieldValue (CustomFieldConstants .CLOUD_UUID );
2716+ VolumeObjectTO volumeTO = (VolumeObjectTO ) vol .getData ();
2717+ DataStoreTO primaryStore = volumeTO .getDataStore ();
2718+ if (actualPoolUuid != null && !actualPoolUuid .equalsIgnoreCase (primaryStore .getUuid ())) {
2719+ volumeDsDetails = new Pair <>(diskDatastoreMofromVM .getMor (), diskDatastoreMofromVM );
2720+ if (s_logger .isInfoEnabled ()) {
2721+ s_logger .info ("Detected datastore uuid change on volume: " + volumeTO .getId () + " " + primaryStore .getUuid () + " -> " + actualPoolUuid );
2722+ }
2723+ ((PrimaryDataStoreTO )primaryStore ).setUuid (actualPoolUuid );
2724+ }
2725+ }
2726+ }
2727+ }
2728+
27122729 private boolean powerOnVM (final VirtualMachineMO vmMo , final String vmInternalCSName , final String vmNameOnVcenter ) throws Exception {
27132730 int retry = 20 ;
27142731 while (retry -- > 0 ) {
0 commit comments