diff --git a/include/History.h b/include/History.h index 6d6931264c..ce7aa5f0d8 100644 --- a/include/History.h +++ b/include/History.h @@ -38,13 +38,11 @@ class History:public ObjectSQL public: enum MigrationReason { - NONE, - ERROR, - STOP_RESUME, - PERFORMANCE, - USER, - RESCHEDULING, - KILL + NONE, /** < Normal termination in host */ + ERROR, /** < The VM was migrated because of an error */ + STOP_RESUME,/** < The VM was migrated because of a stop/resume request*/ + USER, /** < The VM was migrated because of an explicit request */ + CANCEL /** < The VM was migrated because of an explicit cancel */ }; History(int oid, int _seq = -1); diff --git a/include/LifeCycleManager.h b/include/LifeCycleManager.h index 44bd85feb9..b0ddd15702 100644 --- a/include/LifeCycleManager.h +++ b/include/LifeCycleManager.h @@ -52,6 +52,8 @@ public: SHUTDOWN_FAILURE, /**< Send by the VMM when a shutdown action fails */ CANCEL_SUCCESS, /**< Send by the VMM when a cancel action succeeds */ CANCEL_FAILURE, /**< Send by the VMM when a cancel action fails */ + MONITOR_FAILURE, /**< Send by the VMM when a VM has failed while active */ + MONITOR_SUSPEND, /**< Send by the VMM when a VM is paused while active */ PROLOG_SUCCESS, /**< Send by the TM when the prolog phase succeeds */ PROLOG_FAILURE, /**< Send by the TM when the prolog phase fails */ EPILOG_SUCCESS, /**< Send by the TM when the epilog phase succeeds */ @@ -145,6 +147,10 @@ private: void cancel_success_action(int vid); void cancel_failure_action(int vid); + + void monitor_failure_action(int vid); + + void monitor_suspend_action(int vid); void prolog_success_action(int vid); diff --git a/include/VirtualMachine.h b/include/VirtualMachine.h index 705bdc8cb7..251bd5dd2f 100644 --- a/include/VirtualMachine.h +++ b/include/VirtualMachine.h @@ -187,34 +187,28 @@ public: // History // ------------------------------------------------------------------------ /** - * Adds a new history record an writes it in the database. If reason is - * given the update_previous_history MUST be called. + * Adds a new history record an writes it in the database. */ void add_history( int hid, string& hostname, string& vm_dir, string& vmm_mad, - string& tm_mad, - History::MigrationReason reason=History::NONE); + string& tm_mad); /** * Duplicates the last history record. Only the host related fields are - * affected (i.e. no counter is copied nor initialized). If reason is given - * the update_previous_history MUST be called. + * affected (i.e. no counter is copied nor initialized). * @param reason explaining the new addition. */ - void cp_history( - History::MigrationReason reason=History::NONE); + void cp_history(); /** * Duplicates the previous history record. Only the host related fields are - * affected (i.e. no counter is copied nor initialized). If reason is given - * the update_previous_history MUST be called. + * affected (i.e. no counter is copied nor initialized). * @param reason explaining the new addition. */ - void cp_previous_history( - History::MigrationReason reason=History::NONE); + void cp_previous_history(); /** * Checks if the VM has a valid history record. This function @@ -421,6 +415,15 @@ public: { history->reason=_reason; }; + + /** + * Sets the reason that originated the VM migration in the previous host + * @param _reason migration reason to leave this host + */ + void set_previous_reason(History::MigrationReason _reason) + { + previous_history->reason=_reason; + }; // ------------------------------------------------------------------------ // Template diff --git a/src/lcm/LifeCycleActions.cc b/src/lcm/LifeCycleActions.cc index 84c8e8cc62..1d6f24e1ae 100644 --- a/src/lcm/LifeCycleActions.cc +++ b/src/lcm/LifeCycleActions.cc @@ -369,10 +369,8 @@ void LifeCycleManager::restore_action(int vid) vmpool->update(vm); - vm->cp_history(History::STOP_RESUME); - - vmpool->update_previous_history(vm); - + vm->cp_history(); + vm->set_stime(the_time); vm->set_running_stime(the_time); diff --git a/src/lcm/LifeCycleManager.cc b/src/lcm/LifeCycleManager.cc index 0e35469002..05d745987f 100644 --- a/src/lcm/LifeCycleManager.cc +++ b/src/lcm/LifeCycleManager.cc @@ -102,6 +102,14 @@ void LifeCycleManager::trigger(Actions action, int _vid) aname = "CANCEL_FAILURE"; break; + case MONITOR_FAILURE: + aname = "MONITOR_FAILURE"; + break; + + case MONITOR_SUSPEND: + aname = "MONITOR_SUSPEND"; + break; + case PROLOG_SUCCESS: aname = "PROLOG_SUCCESS"; break; @@ -211,6 +219,14 @@ void LifeCycleManager::do_action(const string &action, void * arg) { cancel_failure_action(vid); } + else if (action == "MONITOR_FAILURE") + { + monitor_failure_action(vid); + } + else if (action == "MONITOR_SUSPEND") + { + monitor_suspend_action(vid); + } else if (action == "PROLOG_SUCCESS") { prolog_success_action(vid); diff --git a/src/lcm/LifeCycleStates.cc b/src/lcm/LifeCycleStates.cc index 87a3db7839..7b655d312a 100644 --- a/src/lcm/LifeCycleStates.cc +++ b/src/lcm/LifeCycleStates.cc @@ -52,6 +52,8 @@ void LifeCycleManager::save_success_action(int vid) vm->set_previous_running_etime(the_time); + vm->set_previous_reason(History::USER); + vmpool->update_previous_history(vm); vm->set_prolog_stime(the_time); @@ -82,6 +84,8 @@ void LifeCycleManager::save_success_action(int vid) vm->set_running_etime(the_time); vm->set_etime(the_time); + + vm->set_reason(History::STOP_RESUME); vmpool->update_history(vm); @@ -159,6 +163,8 @@ void LifeCycleManager::save_failure_action(int vid) vm->set_etime(the_time); + vm->set_reason(History::ERROR); + vmpool->update_history(vm); vm->get_requirements(cpu,mem,disk); @@ -169,13 +175,13 @@ void LifeCycleManager::save_failure_action(int vid) vm->set_previous_running_etime(the_time); + vm->set_previous_reason(History::USER); + vmpool->update_previous_history(vm); // --- Add new record by copying the previous one - vm->cp_history(History::ERROR); - - vmpool->update_previous_history(vm); + vm->cp_history(); vm->set_stime(the_time); @@ -246,6 +252,8 @@ void LifeCycleManager::deploy_success_action(int vid) vm->set_previous_running_etime(the_time); + vm->set_previous_reason(History::USER); + vmpool->update_previous_history(vm); vm->get_requirements(cpu,mem,disk); @@ -295,24 +303,26 @@ void LifeCycleManager::deploy_failure_action(int vid) vm->set_etime(the_time); + vm->set_reason(History::ERROR); + vmpool->update_history(vm); - vm->get_requirements(cpu,mem,disk); - - hpool->del_capacity(vm->get_hid(),cpu,mem,disk); - vm->set_previous_etime(the_time); vm->set_previous_running_etime(the_time); + vm->set_previous_reason(History::USER); + vmpool->update_previous_history(vm); + + vm->get_requirements(cpu,mem,disk); + + hpool->del_capacity(vm->get_hid(),cpu,mem,disk); // --- Add new record by copying the previous one - vm->cp_previous_history(History::ERROR); - - vmpool->update_previous_history(vm); - + vm->cp_previous_history(); + vm->set_stime(the_time); vm->set_running_stime(the_time); @@ -337,6 +347,8 @@ void LifeCycleManager::deploy_failure_action(int vid) vm->set_running_etime(the_time); vm->set_etime(the_time); + + vm->set_reason(History::ERROR); vmpool->update_history(vm); @@ -514,6 +526,8 @@ void LifeCycleManager::prolog_failure_action(int vid) vm->set_etime(the_time); + vm->set_reason(History::ERROR); + vmpool->update_history(vm); vm->get_requirements(cpu,mem,disk); @@ -608,6 +622,8 @@ void LifeCycleManager::epilog_failure_action(int vid) vm->set_epilog_etime(the_time); vm->set_etime(the_time); + + vm->set_reason(History::ERROR); vmpool->update_history(vm); @@ -644,6 +660,8 @@ void LifeCycleManager::cancel_success_action(int vid) } vm->set_etime(the_time); + + vm->set_reason(History::CANCEL); vmpool->update_history(vm); @@ -692,3 +710,84 @@ void LifeCycleManager::cancel_failure_action(int vid) vm->unlock(); } + +/* -------------------------------------------------------------------------- */ +/* -------------------------------------------------------------------------- */ + +void LifeCycleManager::monitor_failure_action(int vid) +{ + VirtualMachine * vm; + + int cpu,mem,disk; + time_t the_time = time(0); + + Nebula& nd = Nebula::instance(); + DispatchManager * dm = nd.get_dm(); + + vm = vmpool->get(vid,true); + + if ( vm == 0 ) + { + return; + } + + vm->set_running_etime(the_time); + + vm->set_etime(the_time); + + vm->set_reason(History::ERROR); + + vmpool->update_history(vm); + + vm->get_requirements(cpu,mem,disk); + + hpool->del_capacity(vm->get_hid(),cpu,mem,disk); + + vm->log("LCM", Log::INFO, "VM failed."); + + //---------------------------------------------------- + + dm->trigger(DispatchManager::FAILED,vid); + + vm->unlock(); +} + + +void LifeCycleManager::monitor_suspend_action(int vid) +{ + VirtualMachine * vm; + + int cpu,mem,disk; + time_t the_time = time(0); + + Nebula& nd = Nebula::instance(); + DispatchManager * dm = nd.get_dm(); + + vm = vmpool->get(vid,true); + + if ( vm == 0 ) + { + return; + } + + vm->set_running_etime(the_time); + + vm->set_etime(the_time); + + vm->set_reason(History::STOP_RESUME); + + vmpool->update_history(vm); + + vm->get_requirements(cpu,mem,disk); + + hpool->del_capacity(vm->get_hid(),cpu,mem,disk); + + vm->log("LCM", Log::INFO, "VM is suspended."); + + //---------------------------------------------------- + + dm->trigger(DispatchManager::SUSPEND_SUCCESS,vid); + + + vm->unlock(); +} diff --git a/src/vm/VirtualMachine.cc b/src/vm/VirtualMachine.cc index bbdaed67e5..a3692f4872 100644 --- a/src/vm/VirtualMachine.cc +++ b/src/vm/VirtualMachine.cc @@ -377,8 +377,7 @@ void VirtualMachine::add_history( string& hostname, string& vm_dir, string& vmm_mad, - string& tm_mad, - History::MigrationReason reason) + string& tm_mad) { ostringstream os; int seq; @@ -390,9 +389,7 @@ void VirtualMachine::add_history( else { seq = history->seq + 1; - - history->reason = reason; - + if (previous_history != 0) { delete previous_history; @@ -407,8 +404,7 @@ void VirtualMachine::add_history( /* -------------------------------------------------------------------------- */ /* -------------------------------------------------------------------------- */ -void VirtualMachine::cp_history( - History::MigrationReason reason) +void VirtualMachine::cp_history() { History * htmp; @@ -416,9 +412,7 @@ void VirtualMachine::cp_history( { return; } - - history->reason = reason; - + htmp = new History(oid, history->seq + 1, history->hid, @@ -440,8 +434,7 @@ void VirtualMachine::cp_history( /* -------------------------------------------------------------------------- */ /* -------------------------------------------------------------------------- */ -void VirtualMachine::cp_previous_history( - History::MigrationReason reason) +void VirtualMachine::cp_previous_history() { History * htmp; @@ -450,8 +443,6 @@ void VirtualMachine::cp_previous_history( return; } - history->reason = reason; - htmp = new History(oid, history->seq + 1, previous_history->hid, diff --git a/src/vmm/VirtualMachineManagerDriver.cc b/src/vmm/VirtualMachineManagerDriver.cc index d6d17ffe79..a2f638d18c 100644 --- a/src/vmm/VirtualMachineManagerDriver.cc +++ b/src/vmm/VirtualMachineManagerDriver.cc @@ -350,6 +350,7 @@ void VirtualMachineManagerDriver::protocol( int memory = -1; int net_tx = -1; int net_rx = -1; + char state = '-'; while(is.good()) { @@ -391,6 +392,10 @@ void VirtualMachineManagerDriver::protocol( { tiss >> net_tx; } + else if (var == "STATE") + { + tiss >> state; + } else { os.str(""); @@ -403,6 +408,43 @@ void VirtualMachineManagerDriver::protocol( vm->update_info(memory,cpu,net_tx,net_rx); vmpool->update(vm); + + if (state != '-' && vm->get_lcm_state() == VirtualMachine::RUNNING) + { + Nebula &ne = Nebula::instance(); + LifeCycleManager * lcm = ne.get_lcm(); + + switch (state) + { + case 'a': // Still active, good! + os.str(""); + os << "Monitor Information:\n" + << "\tCPU : "<< cpu << "\n" + << "\tMemory: "<< cpu << "\n" + << "\tNet_TX: "<< cpu << "\n" + << "\tNet_RX: "<< cpu << "\n"; + vm->log("VMM",Log::INFO,os); + break; + + case 'p': // It's paused + os.str(""); + os << "VM running but new state from monitor is PAUSED.\n"; + vm->log("VMM",Log::INFO,os); + + lcm->trigger(LifeCycleManager::MONITOR_SUSPEND, id); + + break; + + case 'e': //Failed + os.str(""); + os << "VM running but new state from monitor is ERROR.\n"; + vm->log("VMM",Log::INFO,os); + + lcm->trigger(LifeCycleManager::MONITOR_FAILURE, id); + + break; + } + } } else {