@@ -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 (logger .isInfoEnabled ())
2416- 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 (logger .isInfoEnabled ())
2426- 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 logger .debug (LogUtils .logGsonWithoutException ("The following definitions will be used to start the VM: virtual device [%s], volume [%s]." , device , volumeTO ));
@@ -2714,6 +2673,64 @@ protected StartAnswer execute(StartCommand cmd) {
27142673 }
27152674 }
27162675
2676+ private Pair <ManagedObjectReference , DatastoreMO > getVolumeDatastoreDetails (DiskTO vol , HashMap <String , Pair <ManagedObjectReference , DatastoreMO >> dataStoresDetails ) throws Exception {
2677+ boolean managed = false ;
2678+ String iScsiName = null ;
2679+ Map <String , String > details = vol .getDetails ();
2680+ if (MapUtils .isNotEmpty (details )) {
2681+ managed = Boolean .parseBoolean (details .get (DiskTO .MANAGED ));
2682+ iScsiName = details .get (DiskTO .IQN );
2683+ }
2684+
2685+ VolumeObjectTO volumeTO = (VolumeObjectTO ) vol .getData ();
2686+ DataStoreTO primaryStore = volumeTO .getDataStore ();
2687+ String primaryStoreUuid = primaryStore .getUuid ();
2688+ // if the storage is managed, iScsiName should not be null
2689+ String datastoreName = managed ? VmwareResource .getDatastoreName (iScsiName ) : primaryStoreUuid ;
2690+ Pair <ManagedObjectReference , DatastoreMO > volumeDsDetails = dataStoresDetails .get (datastoreName );
2691+ if (volumeDsDetails == null ) {
2692+ throw new Exception ("Primary datastore " + primaryStore .getUuid () + " is not mounted on host." );
2693+ }
2694+
2695+ return volumeDsDetails ;
2696+ }
2697+
2698+ private void syncVolumeDatastoreAndPathForDatastoreCluster (DiskTO vol , VirtualMachineDiskInfoBuilder diskInfoBuilder , VirtualMachineDiskInfo matchingExistingDisk ,
2699+ Pair <ManagedObjectReference , DatastoreMO > volumeDsDetails , List <Pair <Integer , ManagedObjectReference >> diskDatastores ,
2700+ VmwareHypervisorHost hyperHost , VmwareContext context ) throws Exception {
2701+ if (vol .getDetails () == null || vol .getDetails ().get (DiskTO .PROTOCOL_TYPE ) == null || !vol .getDetails ().get (DiskTO .PROTOCOL_TYPE ).equalsIgnoreCase ("DatastoreCluster" )) {
2702+ return ;
2703+ }
2704+
2705+ if (diskInfoBuilder != null && matchingExistingDisk != null ) {
2706+ String [] diskChain = matchingExistingDisk .getDiskChain ();
2707+ if (diskChain != null && diskChain .length > 0 ) {
2708+ DatastoreFile file = new DatastoreFile (diskChain [0 ]);
2709+ VolumeObjectTO volumeTO = (VolumeObjectTO ) vol .getData ();
2710+ if (!file .getFileBaseName ().equalsIgnoreCase (volumeTO .getPath ())) {
2711+ if (s_logger .isInfoEnabled ()) {
2712+ s_logger .info ("Detected disk-chain top file change on volume: " + volumeTO .getId () + " " + volumeTO .getPath () + " -> " + file .getFileBaseName ());
2713+ }
2714+ volumeTO .setPath (file .getFileBaseName ());
2715+ vol .setPath (file .getFileBaseName ());
2716+ }
2717+ }
2718+ DatastoreMO diskDatastoreMofromVM = getDataStoreWhereDiskExists (hyperHost , context , diskInfoBuilder , vol , diskDatastores );
2719+ if (diskDatastoreMofromVM != null ) {
2720+ String actualPoolUuid = diskDatastoreMofromVM .getCustomFieldValue (CustomFieldConstants .CLOUD_UUID );
2721+ VolumeObjectTO volumeTO = (VolumeObjectTO ) vol .getData ();
2722+ DataStoreTO primaryStore = volumeTO .getDataStore ();
2723+ if (actualPoolUuid != null && !actualPoolUuid .equalsIgnoreCase (primaryStore .getUuid ())) {
2724+ volumeDsDetails = new Pair <>(diskDatastoreMofromVM .getMor (), diskDatastoreMofromVM );
2725+ if (s_logger .isInfoEnabled ()) {
2726+ s_logger .info ("Detected datastore uuid change on volume: " + volumeTO .getId () + " " + primaryStore .getUuid () + " -> " + actualPoolUuid );
2727+ }
2728+ ((PrimaryDataStoreTO )primaryStore ).setUuid (actualPoolUuid );
2729+ }
2730+ }
2731+ }
2732+ }
2733+
27172734 private boolean powerOnVM (final VirtualMachineMO vmMo , final String vmInternalCSName , final String vmNameOnVcenter ) throws Exception {
27182735 int retry = 20 ;
27192736 while (retry -- > 0 ) {
0 commit comments