Skip to content

Commit a49109a

Browse files
committed
migration working
1 parent 95fe42c commit a49109a

3 files changed

Lines changed: 66 additions & 75 deletions

File tree

engine/orchestration/src/com/cloud/vm/VirtualMachineManagerImpl.java

Lines changed: 62 additions & 68 deletions
Original file line numberDiff line numberDiff line change
@@ -56,6 +56,7 @@
5656
import org.apache.cloudstack.framework.messagebus.MessageBus;
5757
import org.apache.cloudstack.framework.messagebus.MessageDispatcher;
5858
import org.apache.cloudstack.framework.messagebus.MessageHandler;
59+
import org.apache.cloudstack.jobs.JobInfo;
5960
import org.apache.cloudstack.storage.datastore.db.StoragePoolVO;
6061
import org.apache.cloudstack.vm.jobs.VmWorkJobDao;
6162
import org.apache.cloudstack.vm.jobs.VmWorkJobVO;
@@ -511,7 +512,7 @@ public boolean configure(String name, Map<String, Object> xmlParams) throws Conf
511512

512513
_executor = Executors.newScheduledThreadPool(1, new NamedThreadFactory("Vm-Operations-Cleanup"));
513514

514-
_agentMgr.registerForHost)Events(this, true, true, true);
515+
_agentMgr.registerForHostEvents(this, true, true, true);
515516

516517
RootVolumeSearch = _entityMgr.createSearchBuilder(VolumeVO.class);
517518
VolumeVO rvsEntity = RootVolumeSearch.entity();
@@ -1002,10 +1003,10 @@ public void orchestrateStart(String vmUuid, Map<VirtualMachineProfile.Param, Obj
10021003
VmWorkJobVO.Step prevStep = work.getStep();
10031004
_workJobDao.updateStep(work.getId(), VmWorkJobVO.Step.Release);
10041005
if (prevStep == VmWorkJobVO.Step.Started || prevStep == VmWorkJobVO.Step.Starting) {
1005-
cleanup(vmGuru, vmProfile, work, VirtualMachine.Event.OperationFailed, false);
1006+
cleanup(vmGuru, vmProfile, work, false);
10061007
} else {
10071008
//if step is not starting/started, send cleanup command with force=true
1008-
cleanup(vmGuru, vmProfile, work, VirtualMachine.Event.OperationFailed, true);
1009+
cleanup(vmGuru, vmProfile, work, true);
10091010
}
10101011
}
10111012
}
@@ -1225,7 +1226,7 @@ public void orchestrateStop(String vmUuid, boolean forced) throws AgentUnavailab
12251226
}
12261227

12271228
if (doCleanup) {
1228-
if (cleanup(vmGuru, new VirtualMachineProfileImpl(vm), work, VirtualMachine.Event.StopRequested, forced)) {
1229+
if (cleanup(vmGuru, new VirtualMachineProfileImpl(vm), work, forced)) {
12291230
try {
12301231
if (s_logger.isDebugEnabled()) {
12311232
s_logger.debug("Updating work item to Done, id:" + work.getId());
@@ -1589,25 +1590,57 @@ public void orchestrateMigrate(String vmUuid, long srcHostId, DeployDestination
15891590

15901591
_alertMgr.sendAlert(alertType, fromHost.getDataCenterId(), fromHost.getPodId(), "Unable to migrate vm " + vm.getInstanceName() + " from host " + fromHost.getName()
15911592
+ " in zone " + dest.getDataCenter().getName() + " and pod " + dest.getPod().getName(), "Migrate Command failed. Please check logs.");
1593+
1594+
boolean cleanup = false;
15921595
try {
1593-
_agentMgr.send(dstHostId, new Commands(cleanup(vm)), null);
1594-
} catch (AgentUnavailableException ae) {
1595-
s_logger.info("Looks like the destination Host is unavailable for cleanup");
1596+
cleanupMigration(work, dstVm, vm, false);
1597+
cleanup = true;
1598+
} catch (Exception ae) {
1599+
s_logger.warn("Unable to cleanup migration for " + vm);
15961600
}
15971601

1598-
try {
1599-
stateTransitTo(vm, VirtualMachine.Event.OperationFailed, srcHostId);
1600-
} catch (NoTransitionException e) {
1601-
s_logger.warn(e.getMessage());
1602+
if (cleanup) {
1603+
_networkMgr.rollbackNicForMigration(srcVm, dstVm);
1604+
1605+
work.setStep(Step.Done);
1606+
_workJobDao.update(work.getId(), work);
16021607
}
1603-
_networkMgr.rollbackNicForMigration(srcVm, dstVm);
1604-
1605-
work.setStep(Step.Done);
1606-
_workJobDao.update(work.getId(), work);
16071608
}
16081609
}
16091610
}
16101611

1612+
private void determineVmLocation(VirtualMachineProfile vm, VMInstanceVO vo, boolean confirmedStopped) {
1613+
try {
1614+
if (checkVmOnHost(vo, vo.getLastHostId())) {
1615+
stateTransitTo(vo, VirtualMachine.Event.AgentReportRunning, vo.getLastHostId());
1616+
} else if (checkVmOnHost(vo, vo.getHostId())) {
1617+
stateTransitTo(vo, VirtualMachine.Event.AgentReportRunning, vo.getHostId());
1618+
} else {
1619+
s_logger.warn("Unable to find " + vo + " on source " + vo.getLastHostId() + " or on destination " + vo.getHostId()
1620+
+ (!confirmedStopped ? ". Either call Stop with cleanup option or wait for vmsync to check where the VM is." : "."));
1621+
stateTransitTo(vo, VirtualMachine.Event.AgentReportStopped, null);
1622+
}
1623+
} catch (AgentUnavailableException e) {
1624+
if (confirmedStopped) {
1625+
s_logger.debug("Agent is unavailable to determine state for " + vo + " but continuing with confirmed stopped option");
1626+
} else {
1627+
throw new CloudRuntimeException("Unable to determine the state for " + vo).add(VirtualMachine.class, vo.getUuid());
1628+
}
1629+
} catch (OperationTimedoutException e) {
1630+
if (confirmedStopped) {
1631+
s_logger.debug("Operation timedout while determining state for " + vo + " but continuing with confirmed stopped option");
1632+
} else {
1633+
throw new CloudRuntimeException("Unable to determine the state for " + vo).add(VirtualMachine.class, vo.getUuid());
1634+
}
1635+
} catch (NoTransitionException e) {
1636+
throw new CloudRuntimeException("Unable to change VM state ", e).add(VirtualMachine.class, vo.getUuid());
1637+
}
1638+
1639+
if (confirmedStopped) {
1640+
s_logger.info("Cleanup was requested on " + vo);
1641+
cleanup(getVmGuru(vo), vm, null, true);
1642+
}
1643+
}
16111644
/**
16121645
* Migration goes through the following steps.
16131646
* Prepare - nics and storage are prepared
@@ -1622,8 +1655,6 @@ public void orchestrateMigrate(String vmUuid, long srcHostId, DeployDestination
16221655
* @param vo - vo object representing the VM.
16231656
*/
16241657
private void cleanupMigration(VmWorkJobVO job, VirtualMachineProfile vm, VMInstanceVO vo, boolean confirmedStopped) {
1625-
boolean uncertain = false;
1626-
boolean rollbackPreparation = false;
16271658
if (job == null) {
16281659
s_logger.info("Cleaning up " + vo + " with no job to track progress");
16291660
if (vo.getState() != VirtualMachine.State.Migrating) {
@@ -1632,48 +1663,20 @@ private void cleanupMigration(VmWorkJobVO job, VirtualMachineProfile vm, VMInsta
16321663
}
16331664
return;
16341665
}
1635-
if (checkVmOnHost(vo, vo.getLastHostId())) {
1636-
stateTransitTo(vo, VirtualMachine.Event.AgentReportRunning, vo.getLastHostId());
1637-
} else if (checkVmOnHost(vo, vo.getHostId())) {
1638-
stateTransitTo(vo, VirtualMachine.Event.AgentReportRunning, vo.getHostId());
1639-
} else {
1640-
s_logger.warn("Unable to find " + vo + " on source " + vo.getLastHostId() + " or on destination " + vo.getHostId() + (!confirmedStopped ? ". Either call Stop with cleanup option or wait for vmsync to check where the VM is." : "."));
1641-
}
1642-
1643-
if (confirmedStopped) {
1644-
s_logger.info("Cleanup was requested on " + vo);
1645-
cleanup(getVmGuru(vo), vm, null, true);
1646-
}
1666+
determineVmLocation(vm, vo, confirmedStopped);
16471667
return;
16481668
}
16491669

16501670
Step step = job.getStep();
16511671

1652-
s_logger.info("Cleaning up based on what stage the current job is at: " + step);
1672+
if (s_logger.isDebugEnabled()) {
1673+
s_logger.debug("Migration operation was at " + step + " for " + vo);
1674+
}
16531675
if (step == Step.Started) {
1654-
if (checkVmOnHost(vo, vo.getLastHostId())) {
1655-
changeState2(vo, VirtualMachine.Event.AgentReportRunning, vo.getHostId(), job, Event.OperationSucceeded);
1656-
} else {
1657-
changeState2(vo, VirtualMachine.Event.AgentReportStopped, vo.getHostId(), job, Event.OperationFailed);
1658-
}
1676+
determineVmLocation(vm, vo, confirmedStopped);
16591677
} else if (step == Step.Migrating) {
1660-
s_logger.debug("We are at the migrating step. We have to find out if the operation succeeded or ");
1661-
}
1662-
if (step == Step.Prepare) {
1663-
s_logger.debug("Prepare Step: ");
1664-
rollbackPreparation = true;
1665-
}
1666-
1667-
if (uncertain) {
1668-
Long srcHostId = vo.getLastHostId();
1669-
Long dstHostId = vo.getHostId();
1670-
1671-
if (!checkVmOnHost(vo, srcHostId)) {
1672-
changeState2(vo, Event.OperationFailed, job,)
1673-
}
1674-
1678+
determineVmLocation(vm, vo, confirmedStopped);
16751679
}
1676-
16771680
}
16781681

16791682

@@ -1827,7 +1830,7 @@ public VirtualMachine migrateWithStorage(String vmUuid, long srcHostId, long des
18271830
} catch (AgentUnavailableException e) {
18281831
s_logger.error("AgentUnavailableException while cleanup on source host: " + srcHostId);
18291832
}
1830-
cleanup(vmGuru, new VirtualMachineProfileImpl(vm), work, VirtualMachine.Event.AgentReportStopped, true);
1833+
cleanup(vmGuru, new VirtualMachineProfileImpl(vm), work, true);
18311834
return null;
18321835
}
18331836
} catch (OperationTimedoutException e) {
@@ -1952,27 +1955,18 @@ public boolean migrateAway(VirtualMachine.Type vmType, long vmId, long srcHostId
19521955

19531956
excludes.addHost(dest.getHost().getId());
19541957
VirtualMachine vmInstance = null;
1958+
Outcome<VirtualMachine> outcome = migrate(vm.getUuid(), srcHostId, dest);
19551959
try {
1956-
vmInstance = migrate(vm.getUuid(), srcHostId, dest);
1957-
} catch (ResourceUnavailableException e) {
1958-
s_logger.debug("Unable to migrate to unavailable " + dest);
1959-
} catch (ConcurrentOperationException e) {
1960-
s_logger.debug("Unable to migrate VM due to: " + e.getMessage());
1961-
} catch (ManagementServerException e) {
1962-
s_logger.debug("Unable to migrate VM: " + e.getMessage());
1963-
} catch (VirtualMachineMigrationException e) {
1964-
s_logger.debug("Got VirtualMachineMigrationException, Unable to migrate: " + e.getMessage());
1965-
if (vm.getState() == State.Starting) {
1966-
s_logger.debug("VM seems to be still Starting, we should retry migration later");
1967-
throw e;
1968-
} else {
1969-
s_logger.debug("Unable to migrate VM, VM is not in Running or even Starting state, current state: " + vm.getState().toString());
1970-
}
1960+
vmInstance = outcome.get();
1961+
} catch (InterruptedException e1) {
1962+
s_logger.warn("Unable to migrate teh VM", e1);
1963+
} catch (java.util.concurrent.ExecutionException e1) {
1964+
s_logger.warn("Unable to migrate the VM", e1);
19711965
}
19721966
if (vmInstance != null) {
19731967
return true;
19741968
}
1975-
Outcome<VirtualMachine> outcome = stop(vm.getUuid(), true);
1969+
outcome = stop(vm.getUuid(), true);
19761970
try {
19771971
outcome.get(_jobTimeout.value(), TimeUnit.MILLISECONDS);
19781972
return true;

engine/orchestration/test/com/cloud/vm/VmWorkTest.java

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -112,7 +112,7 @@ public void testDeployPlanSerialization() {
112112

113113
@Test
114114
public void testVmWorkStart() {
115-
VmWorkStart work = new VmWorkStart();
115+
VmWorkStart work = new VmWorkStart(1L, 1L, 1L);
116116
Map<VirtualMachineProfile.Param, Object> params = new HashMap<VirtualMachineProfile.Param, Object>();
117117
params.put(VirtualMachineProfile.Param.HaTag, "HA");
118118
params.put(VirtualMachineProfile.Param.ControlNic, new Long(100));
@@ -133,12 +133,12 @@ public void testVmWorkDispatcher() {
133133
workJob.setVmType(VirtualMachine.Type.ConsoleProxy);
134134
workJob.setVmInstanceId(1L);
135135

136-
VmWorkStart workInfo = new VmWorkStart();
136+
VmWorkStart workInfo = new VmWorkStart(1L, 1L, 1L);
137137
workJob.setCmdInfo(VmWorkJobDispatcher.serialize(workInfo));
138138

139139
_jobMgr.submitAsyncJob(workJob, "VM", 1);
140140

141-
_jobMgr.waitAndCheck(new String[] {"Done"}, 120000, 120000, new Predicate() {
141+
_jobMgr.waitAndCheck(workJob, new String[] {"Done"}, 120000, 120000, new Predicate() {
142142

143143
@Override
144144
public boolean checkCondition() {

engine/orchestration/test/com/cloud/vm/VmWorkTestApiJobDispatcher.java

Lines changed: 1 addition & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -65,10 +65,7 @@ public void runJob(AsyncJob job) {
6565
workJob.setVmInstanceId(1L);
6666

6767
// save work context info (there are some duplications)
68-
VmWorkStart workInfo = new VmWorkStart();
69-
workInfo.setAccountId(1L);
70-
workInfo.setUserId(1L);
71-
workInfo.setVmId(1L);
68+
VmWorkStart workInfo = new VmWorkStart(1L, 1L, 1L);
7269
workInfo.setPlan(null);
7370
workInfo.setParams(null);
7471
workJob.setCmdInfo(VmWorkJobDispatcher.serialize(workInfo));

0 commit comments

Comments
 (0)