diff --git a/include/DispatchManager.h b/include/DispatchManager.h index 789acd1ba2..52083be6e0 100644 --- a/include/DispatchManager.h +++ b/include/DispatchManager.h @@ -44,10 +44,11 @@ public: enum Actions { - SUSPEND_SUCCESS, /**< Send by LCM when a VM is suspended*/ - STOP_SUCCESS, /**< Send by LCM when a VM is stopped*/ - DONE, /**< Send by LCM when a VM is shut down*/ - FAILED, /**< Send by LCM when one of the execution steps fails*/ + SUSPEND_SUCCESS,/**< Send by LCM when a VM is suspended*/ + STOP_SUCCESS, /**< Send by LCM when a VM is stopped*/ + DONE, /**< Send by LCM when a VM is shut down*/ + FAILED, /**< Send by LCM when one of the execution steps fails*/ + RESUBMIT, /**< Send by LCM when a VM is ready for resubmission*/ FINALIZE }; @@ -200,6 +201,15 @@ public: int finalize( int vid); + /** + * Moves a VM to PENDING state preserving any resource (i.e. leases) and id + * @param vid VirtualMachine identification + * @return 0 on success, -1 if the VM does not exits or -2 if the VM is + * in a wrong a state + */ + int resubmit( + int vid); + private: /** * Thread id for the Dispatch Manager @@ -247,7 +257,8 @@ private: void done_action(int vid); void failed_action(int vid); + + void resubmit_action(int vid); }; #endif /*DISPATCH_MANAGER_H*/ - diff --git a/include/LifeCycleManager.h b/include/LifeCycleManager.h index 9ad150dcf1..eb3f336a11 100644 --- a/include/LifeCycleManager.h +++ b/include/LifeCycleManager.h @@ -68,6 +68,7 @@ public: SHUTDOWN, /**< Sent by the DM to shutdown a running VM */ RESTART, /**< Sent by the DM to restart a deployed VM */ DELETE, /**< Sent by the DM to delete a VM */ + CLEAN, /**< Sent by the DM to cleanup a VM for resubmission*/ FINALIZE }; @@ -195,6 +196,8 @@ private: void delete_action(int vid); + void clean_action(int vid); + void timer_action(); }; diff --git a/src/dm/DispatchManager.cc b/src/dm/DispatchManager.cc index 89044f8e12..196005aabc 100644 --- a/src/dm/DispatchManager.cc +++ b/src/dm/DispatchManager.cc @@ -85,6 +85,10 @@ void DispatchManager::trigger(Actions action, int _vid) aname = "FAILED"; break; + case RESUBMIT: + aname = "RESUBMIT"; + break; + case FINALIZE: aname = ACTION_FINALIZE; break; @@ -130,6 +134,10 @@ void DispatchManager::do_action(const string &action, void * arg) { failed_action(vid); } + else if (action == "RESUBMIT") + { + resubmit_action(vid); + } else if (action == ACTION_FINALIZE) { NebulaLog::log("DiM",Log::INFO,"Stopping Dispatch Manager..."); diff --git a/src/dm/DispatchManagerActions.cc b/src/dm/DispatchManagerActions.cc index a82485f14e..46d7a103e0 100644 --- a/src/dm/DispatchManagerActions.cc +++ b/src/dm/DispatchManagerActions.cc @@ -597,3 +597,58 @@ int DispatchManager::finalize( return 0; } +/* -------------------------------------------------------------------------- */ +/* -------------------------------------------------------------------------- */ + +int DispatchManager::resubmit(int vid) +{ + VirtualMachine * vm; + ostringstream oss; + int rc = 0; + + Nebula& nd = Nebula::instance(); + LifeCycleManager * lcm = nd.get_lcm(); + + vm = vmpool->get(vid,true); + + if ( vm == 0 ) + { + return -1; + } + + switch (vm->get_state()) + { + case VirtualMachine::SUSPENDED: + NebulaLog::log("DiM",Log::ERROR, + "Can not resubmit a suspended VM. Resume it first"); + rc = -2; + break; + + case VirtualMachine::INIT: // No need to do nothing here + case VirtualMachine::PENDING: + break; + + case VirtualMachine::HOLD: // Move the VM to PENDING in any of these + case VirtualMachine::STOPPED: + case VirtualMachine::FAILED: + vm->set_state(VirtualMachine::LCM_INIT); + vm->set_state(VirtualMachine::PENDING); + vmpool->update(vm); + + vm->log("DiM", Log::INFO, "New VM state is PENDING."); + break; + + case VirtualMachine::ACTIVE: //Cleanup VM resources before PENDING + lcm->trigger(LifeCycleManager::CLEAN,vid); + break; + case VirtualMachine::DONE: + NebulaLog::log("DiM",Log::ERROR, + "Can not resubmit a VM already in DONE state"); + rc = -2; + break; + } + + vm->unlock(); + + return rc; +} diff --git a/src/dm/DispatchManagerStates.cc b/src/dm/DispatchManagerStates.cc index 650b23d92f..2b54332837 100644 --- a/src/dm/DispatchManagerStates.cc +++ b/src/dm/DispatchManagerStates.cc @@ -179,3 +179,34 @@ void DispatchManager::failed_action(int vid) /* -------------------------------------------------------------------------- */ /* -------------------------------------------------------------------------- */ + +void DispatchManager::resubmit_action(int vid) +{ + VirtualMachine * vm; + + vm = vmpool->get(vid,true); + + if ( vm == 0 ) + { + return; + } + + if (vm->get_lcm_state() == VirtualMachine::CLEANUP) + { + + vm->set_state(VirtualMachine::LCM_INIT); + + vm->set_state(VirtualMachine::PENDING); + + vmpool->update(vm); + + vm->log("DiM", Log::INFO, "New VM state is PENDING"); + + vm->unlock(); + } + + return; +} + +/* -------------------------------------------------------------------------- */ +/* -------------------------------------------------------------------------- */ diff --git a/src/lcm/LifeCycleActions.cc b/src/lcm/LifeCycleActions.cc index c36e479ce0..68554a413a 100644 --- a/src/lcm/LifeCycleActions.cc +++ b/src/lcm/LifeCycleActions.cc @@ -518,11 +518,13 @@ void LifeCycleManager::delete_action(int vid) /* -------------------------------------------------------------------------- */ /* -------------------------------------------------------------------------- */ -/* -void LifeCycleManager::resubmit_action(int vid) +void LifeCycleManager::clean_action(int vid) { VirtualMachine * vm; + Nebula& nd = Nebula::instance(); + DispatchManager * dm = nd.get_dm(); + vm = vmpool->get(vid,true); if ( vm == 0 ) @@ -533,25 +535,20 @@ void LifeCycleManager::resubmit_action(int vid) VirtualMachine::LcmState state = vm->get_lcm_state(); if ((state == VirtualMachine::LCM_INIT) || -//TBD (state == VirtualMachine::DELETE) || + (state == VirtualMachine::CLEANUP) || (state == VirtualMachine::FAILURE)) { vm->unlock(); return; } -//TBD - reuse DELETE or rename to CLEAN vm->set_state(VirtualMachine::DELETE); - vmpool->update(vm); + clean_up_vm(vm); - clean_up_vm(vm,state); - -//TBD dm->trigger(DispatchManager::RESUBMIT,vid); + dm->trigger(DispatchManager::RESUBMIT,vid); vm->unlock(); - - return; } -*/ + /* -------------------------------------------------------------------------- */ /* -------------------------------------------------------------------------- */ diff --git a/src/lcm/LifeCycleManager.cc b/src/lcm/LifeCycleManager.cc index d65fcb691c..64fb2b36a2 100644 --- a/src/lcm/LifeCycleManager.cc +++ b/src/lcm/LifeCycleManager.cc @@ -36,8 +36,8 @@ extern "C" void * lcm_action_loop(void *arg) lcm->am.loop(0,0); NebulaLog::log("LCM",Log::INFO,"Life-cycle Manager stopped."); - - return 0; + + return 0; } /* -------------------------------------------------------------------------- */ @@ -51,7 +51,7 @@ int LifeCycleManager::start() pthread_attr_setdetachstate (&pattr, PTHREAD_CREATE_JOINABLE); NebulaLog::log("LCM",Log::INFO,"Starting Life-cycle Manager..."); - + rc = pthread_create(&lcm_thread,&pattr,lcm_action_loop,(void *) this); return rc; @@ -88,7 +88,7 @@ void LifeCycleManager::trigger(Actions action, int _vid) case SHUTDOWN_SUCCESS: aname = "SHUTDOWN_SUCCESS"; break; - + case SHUTDOWN_FAILURE: aname = "SHUTDOWN_FAILURE"; break; @@ -96,7 +96,7 @@ void LifeCycleManager::trigger(Actions action, int _vid) case CANCEL_SUCCESS: aname = "CANCEL_SUCCESS"; break; - + case CANCEL_FAILURE: aname = "CANCEL_FAILURE"; break; @@ -104,7 +104,7 @@ void LifeCycleManager::trigger(Actions action, int _vid) case MONITOR_FAILURE: aname = "MONITOR_FAILURE"; break; - + case MONITOR_SUSPEND: aname = "MONITOR_SUSPEND"; break; @@ -132,7 +132,7 @@ void LifeCycleManager::trigger(Actions action, int _vid) case DEPLOY: aname = "DEPLOY"; break; - + case SUSPEND: aname = "SUSPEND"; break; @@ -160,7 +160,7 @@ void LifeCycleManager::trigger(Actions action, int _vid) case SHUTDOWN: aname = "SHUTDOWN"; break; - + case RESTART: aname = "RESTART"; break; @@ -169,10 +169,14 @@ void LifeCycleManager::trigger(Actions action, int _vid) aname = "DELETE"; break; + case CLEAN: + aname = "CLEAN"; + break; + case FINALIZE: aname = ACTION_FINALIZE; break; - + default: delete vid; return; @@ -188,7 +192,7 @@ void LifeCycleManager::do_action(const string &action, void * arg) { int vid; ostringstream oss; - + if (arg == 0) { return; @@ -197,7 +201,7 @@ void LifeCycleManager::do_action(const string &action, void * arg) vid = *(static_cast(arg)); delete static_cast(arg); - + if (action == "SAVE_SUCCESS") { save_success_action(vid); @@ -232,16 +236,16 @@ void LifeCycleManager::do_action(const string &action, void * arg) } else if (action == "MONITOR_FAILURE") { - monitor_failure_action(vid); + monitor_failure_action(vid); } else if (action == "MONITOR_SUSPEND") { - monitor_suspend_action(vid); + monitor_suspend_action(vid); } else if (action == "MONITOR_DONE") { - monitor_done_action(vid); - } + monitor_done_action(vid); + } else if (action == "PROLOG_SUCCESS") { prolog_success_action(vid); @@ -256,7 +260,7 @@ void LifeCycleManager::do_action(const string &action, void * arg) } else if (action == "EPILOG_FAILURE") { - epilog_failure_action(vid); + epilog_failure_action(vid); } else if (action == "DEPLOY") { @@ -298,6 +302,10 @@ void LifeCycleManager::do_action(const string &action, void * arg) { delete_action(vid); } + else if (action == "CLEAN") + { + clean_action(vid); + } else if (action == ACTION_FINALIZE) { NebulaLog::log("LCM",Log::INFO,"Stopping Life-cycle Manager..."); @@ -306,11 +314,10 @@ void LifeCycleManager::do_action(const string &action, void * arg) { ostringstream oss; oss << "Unknown action name: " << action; - + NebulaLog::log("LCM", Log::ERROR, oss); } } /* -------------------------------------------------------------------------- */ /* -------------------------------------------------------------------------- */ -