@@ -3104,7 +3104,7 @@ protected void migrate(final VMInstanceVO vm, final long srcHostId, final Deploy
31043104 updateOverCommitRatioForVmProfile (profile , dest .getHost ().getClusterId ());
31053105
31063106 final VirtualMachineTO to = toVmTO (profile );
3107- final PrepareForMigrationCommand pfmc = new PrepareForMigrationCommand (to );
3107+ final PrepareForMigrationCommand pfmcDest = new PrepareForMigrationCommand (to , false );
31083108 setVmNetworkDetails (vm , to );
31093109
31103110 ItWorkVO work = new ItWorkVO (UUID .randomUUID ().toString (), _nodeId , State .Migrating , vm .getType (), vm .getId ());
@@ -3113,19 +3113,42 @@ protected void migrate(final VMInstanceVO vm, final long srcHostId, final Deploy
31133113 work .setResourceId (dstHostId );
31143114 work = _workDao .persist (work );
31153115
3116- Answer pfma = null ;
3116+ // For KVM, we need to prepare both source and destination before migration because of the way KVM handles storage during migration.
3117+ // For other hypervisors, we only need to prepare the destination before migration.
3118+ if (HypervisorType .KVM .equals (vm .getHypervisorType ())) {
3119+ final PrepareForMigrationCommand pfmcSource = new PrepareForMigrationCommand (to , true );
3120+ Answer pfmaSource = null ;
3121+ try {
3122+ pfmaSource = _agentMgr .send (srcHostId , pfmcSource );
3123+ if (pfmaSource == null || !pfmaSource .getResult ()) {
3124+ final String details = pfmaSource != null ? pfmaSource .getDetails () : "null answer returned" ;
3125+ pfmaSource = null ;
3126+ throw new AgentUnavailableException (String .format ("Unable to prepare source for migration due to [%s]." , details ), srcHostId );
3127+ }
3128+ } catch (final OperationTimedoutException e1 ) {
3129+ throw new AgentUnavailableException ("Operation timed out" , srcHostId );
3130+ } finally {
3131+ if (pfmaSource == null ) {
3132+ _networkMgr .rollbackNicForMigration (vmSrc , profile );
3133+ volumeMgr .release (vm .getId (), dstHostId );
3134+ work .setStep (Step .Done );
3135+ _workDao .update (work .getId (), work );
3136+ }
3137+ }
3138+ }
3139+
3140+ Answer pfmaDest = null ;
31173141 try {
3118- pfma = _agentMgr .send (dstHostId , pfmc );
3119- if (pfma == null || !pfma .getResult ()) {
3120- final String details = pfma != null ? pfma .getDetails () : "null answer returned" ;
3121- final String msg = "Unable to prepare for migration due to " + details ;
3122- pfma = null ;
3123- throw new AgentUnavailableException (msg , dstHostId );
3142+ pfmaDest = _agentMgr .send (dstHostId , pfmcDest );
3143+ if (pfmaDest == null || !pfmaDest .getResult ()) {
3144+ final String details = pfmaDest != null ? pfmaDest .getDetails () : "null answer returned" ;
3145+ pfmaDest = null ;
3146+ throw new AgentUnavailableException ("Unable to prepare destination for migration due to " + details , dstHostId );
31243147 }
31253148 } catch (final OperationTimedoutException e1 ) {
31263149 throw new AgentUnavailableException ("Operation timed out" , dstHostId );
31273150 } finally {
3128- if (pfma == null ) {
3151+ if (pfmaDest == null ) {
31293152 _networkMgr .rollbackNicForMigration (vmSrc , profile );
31303153 volumeMgr .release (vm .getId (), dstHostId );
31313154 work .setStep (Step .Done );
@@ -3167,7 +3190,7 @@ protected void migrate(final VMInstanceVO vm, final long srcHostId, final Deploy
31673190 boolean migrated = false ;
31683191 Map <String , DpdkTO > dpdkInterfaceMapping = new HashMap <>();
31693192 try {
3170- final MigrateCommand mc = buildMigrateCommand (vm , to , dest , pfma , dpdkInterfaceMapping );
3193+ final MigrateCommand mc = buildMigrateCommand (vm , to , dest , pfmaDest , dpdkInterfaceMapping );
31713194
31723195 try {
31733196 final Answer ma = _agentMgr .send (vm .getLastHostId (), mc );
@@ -4897,26 +4920,48 @@ private void orchestrateMigrateForScale(final String vmUuid, final long srcHostI
48974920 volumeMgr .prepareForMigration (profile , dest );
48984921
48994922 final VirtualMachineTO to = toVmTO (profile );
4900- final PrepareForMigrationCommand pfmc = new PrepareForMigrationCommand (to );
4923+ final PrepareForMigrationCommand pfmcDest = new PrepareForMigrationCommand (to , false );
49014924
49024925 ItWorkVO work = new ItWorkVO (UUID .randomUUID ().toString (), _nodeId , State .Migrating , vm .getType (), vm .getId ());
49034926 work .setStep (Step .Prepare );
49044927 work .setResourceType (ItWorkVO .ResourceType .Host );
49054928 work .setResourceId (dstHostId );
49064929 work = _workDao .persist (work );
49074930
4908- Answer pfma = null ;
4931+ // For KVM, we need to prepare both source and destination before migration because of the way KVM handles storage during migration.
4932+ // For other hypervisors, we only need to prepare the destination before migration.
4933+ if (HypervisorType .KVM .equals (vm .getHypervisorType ())) {
4934+ final PrepareForMigrationCommand pfmcSource = new PrepareForMigrationCommand (to , true );
4935+ Answer pfmaSource = null ;
4936+ try {
4937+ pfmaSource = _agentMgr .send (srcHostId , pfmcSource );
4938+ if (pfmaSource == null || !pfmaSource .getResult ()) {
4939+ final String details = pfmaSource != null ? pfmaSource .getDetails () : "null answer returned" ;
4940+ pfmaSource = null ;
4941+ throw new AgentUnavailableException (String .format ("Unable to prepare source for migration due to [%s]." , details ), srcHostId );
4942+ }
4943+ } catch (final OperationTimedoutException e1 ) {
4944+ throw new AgentUnavailableException ("Operation timed out" , srcHostId );
4945+ } finally {
4946+ if (pfmaSource == null ) {
4947+ work .setStep (Step .Done );
4948+ _workDao .update (work .getId (), work );
4949+ }
4950+ }
4951+ }
4952+
4953+ Answer pfmaDest = null ;
49094954 try {
4910- pfma = _agentMgr .send (dstHostId , pfmc );
4911- if (pfma == null || !pfma .getResult ()) {
4912- final String details = pfma != null ? pfma .getDetails () : "null answer returned" ;
4913- pfma = null ;
4955+ pfmaDest = _agentMgr .send (dstHostId , pfmcDest );
4956+ if (pfmaDest == null || !pfmaDest .getResult ()) {
4957+ final String details = pfmaDest != null ? pfmaDest .getDetails () : "null answer returned" ;
4958+ pfmaDest = null ;
49144959 throw new AgentUnavailableException (String .format ("Unable to prepare for migration to destination host [%s] due to [%s]." , dest .getHost (), details ), dstHostId );
49154960 }
49164961 } catch (final OperationTimedoutException e1 ) {
49174962 throw new AgentUnavailableException ("Operation timed out" , dstHostId );
49184963 } finally {
4919- if (pfma == null ) {
4964+ if (pfmaDest == null ) {
49204965 work .setStep (Step .Done );
49214966 _workDao .update (work .getId (), work );
49224967 }
@@ -4937,7 +4982,7 @@ private void orchestrateMigrateForScale(final String vmUuid, final long srcHostI
49374982
49384983 boolean migrated = false ;
49394984 try {
4940- final MigrateCommand mc = buildMigrateCommand (vm , to , dest , pfma , null );
4985+ final MigrateCommand mc = buildMigrateCommand (vm , to , dest , pfmaDest , null );
49414986
49424987 try {
49434988 final Answer ma = _agentMgr .send (vm .getLastHostId (), mc );
0 commit comments