1
0
mirror of https://github.com/OpenNebula/one.git synced 2025-01-03 01:17:41 +03:00

Feature #1839: New action shutdown-save(-hard) in core

This commit is contained in:
Carlos Martín 2013-03-27 18:15:53 +01:00
parent 12faca7d16
commit 675d936741
12 changed files with 273 additions and 5 deletions

View File

@ -46,6 +46,7 @@ public:
{
SUSPEND_SUCCESS,/**< Send by LCM when a VM is suspended*/
STOP_SUCCESS, /**< Send by LCM when a VM is stopped*/
SHUTDOWN_SAVE_SUCCESS, /**< Send by LCM when a VM is shut down and saved*/
POWEROFF_SUCCESS, /**< Send by LCM when a VM is powered off */
DONE, /**< Send by LCM when a VM is shut down*/
FAILED, /**< Send by LCM when one of the execution steps fails*/
@ -130,6 +131,17 @@ public:
int shutdown (
int vid);
/**
* Shuts down a VM, but it is saved in the system DS instead of destroyed.
* @param vid VirtualMachine identification
* @param hard True to force the shutdown (cancel instead of shutdown)
* @return 0 on success, -1 if the VM does not exits or -2 if the VM is
* in a wrong a state
*/
int shutdown_save(
int vid,
bool hard);
/**
* Powers off a VM.
* @param vid VirtualMachine identification
@ -396,6 +408,8 @@ private:
void stop_success_action(int vid);
void shutdown_save_success_action(int vid);
void poweroff_success_action(int vid);
void done_action(int vid);

View File

@ -84,6 +84,8 @@ public:
MIGRATE, /**< Sent by the DM to migrate a VM to other host */
LIVE_MIGRATE, /**< Sent by the DM to live-migrate a VM */
SHUTDOWN, /**< Sent by the DM to shutdown a running VM */
SHUTDOWN_SAVE, /**< Sent by the DM to shutdown a running VM */
SHUTDOWN_SAVE_HARD, /**< Sent by the DM to shutdown a running VM */
POWEROFF, /**< Sent by the DM to power off a running VM */
RESTART, /**< Sent by the DM to restart a deployed VM */
DELETE, /**< Sent by the DM to delete a VM */
@ -247,6 +249,8 @@ private:
void shutdown_action(int vid);
void shutdown_save_action(int vid, bool hard);
void poweroff_action(int vid);
void failure_action(VirtualMachine * vm);

View File

@ -58,7 +58,8 @@ public:
SUSPENDED = 5,
DONE = 6,
FAILED = 7,
POWEROFF = 8
POWEROFF = 8,
SHUTDOWN_SAVED = 9
};
/**
@ -94,7 +95,9 @@ public:
HOTPLUG_NIC = 25,
HOTPLUG_SAVEAS = 26,
HOTPLUG_SAVEAS_POWEROFF = 27,
HOTPLUG_SAVEAS_SUSPENDED = 28
HOTPLUG_SAVEAS_SUSPENDED = 28,
SHUTDOWN_SAVE = 29,
EPILOG_SHUTDOWN_SAVE = 30
};
// -------------------------------------------------------------------------

View File

@ -77,6 +77,10 @@ void DispatchManager::trigger(Actions action, int _vid)
aname = "STOP_SUCCESS";
break;
case SHUTDOWN_SAVE_SUCCESS:
aname = "SHUTDOWN_SAVE_SUCCESS";
break;
case POWEROFF_SUCCESS:
aname = "POWEROFF_SUCCESS";
break;
@ -130,6 +134,10 @@ void DispatchManager::do_action(const string &action, void * arg)
{
stop_success_action(vid);
}
else if (action == "SHUTDOWN_SAVE_SUCCESS")
{
shutdown_save_success_action(vid);
}
else if (action == "POWEROFF_SUCCESS")
{
poweroff_success_action(vid);

View File

@ -209,6 +209,59 @@ error:
/* -------------------------------------------------------------------------- */
/* -------------------------------------------------------------------------- */
int DispatchManager::shutdown_save(
int vid,
bool hard)
{
VirtualMachine * vm;
ostringstream oss;
vm = vmpool->get(vid,true);
if ( vm == 0 )
{
return -1;
}
oss << "Shutting down VM " << vid;
NebulaLog::log("DiM",Log::DEBUG,oss);
if (vm->get_state() == VirtualMachine::ACTIVE &&
vm->get_lcm_state() == VirtualMachine::RUNNING )
{
Nebula& nd = Nebula::instance();
LifeCycleManager * lcm = nd.get_lcm();
if (hard)
{
lcm->trigger(LifeCycleManager::SHUTDOWN_SAVE_HARD,vid);
}
else
{
lcm->trigger(LifeCycleManager::SHUTDOWN_SAVE,vid);
}
}
else
{
goto error;
}
vm->unlock();
return 0;
error:
oss.str("");
oss << "Could not shutdown VM " << vid << ", wrong state.";
NebulaLog::log("DiM",Log::ERROR,oss);
vm->unlock();
return -2;
}
/* -------------------------------------------------------------------------- */
/* -------------------------------------------------------------------------- */
int DispatchManager::poweroff (
int vid)
{
@ -804,6 +857,7 @@ int DispatchManager::finalize(
break;
case VirtualMachine::STOPPED:
case VirtualMachine::SHUTDOWN_SAVED:
tm->trigger(TransferManager::EPILOG_DELETE_STOP,vid);
finalize_cleanup(vm);
break;
@ -878,6 +932,7 @@ int DispatchManager::resubmit(int vid)
case VirtualMachine::HOLD: // Move the VM to PENDING in any of these
case VirtualMachine::STOPPED:
case VirtualMachine::SHUTDOWN_SAVED:
vm->set_state(VirtualMachine::LCM_INIT);
vm->set_state(VirtualMachine::PENDING);

View File

@ -98,6 +98,48 @@ void DispatchManager::stop_success_action(int vid)
/* -------------------------------------------------------------------------- */
/* -------------------------------------------------------------------------- */
void DispatchManager::shutdown_save_success_action(int vid)
{
VirtualMachine * vm;
vm = vmpool->get(vid,true);
if ( vm == 0 )
{
return;
}
// TODO: prolog_resume, or new prolog?
if ((vm->get_state() == VirtualMachine::ACTIVE) &&
(vm->get_lcm_state() == VirtualMachine::EPILOG_SHUTDOWN_SAVE ||
vm->get_lcm_state() == VirtualMachine::PROLOG_RESUME))
{
vm->set_state(VirtualMachine::SHUTDOWN_SAVED);
vm->set_state(VirtualMachine::LCM_INIT);
vmpool->update(vm);
vm->log("DiM", Log::INFO, "New VM state is SHUTDOWN_SAVED");
}
else
{
ostringstream oss;
oss << "shutdown_save_success action received but VM " << vid
<< " not in ACTIVE state";
NebulaLog::log("DiM",Log::ERROR,oss);
}
vm->unlock();
return;
}
/* -------------------------------------------------------------------------- */
/* -------------------------------------------------------------------------- */
void DispatchManager::poweroff_success_action(int vid)
{
VirtualMachine * vm;

View File

@ -334,6 +334,60 @@ void LifeCycleManager::shutdown_action(int vid)
return;
}
/* -------------------------------------------------------------------------- */
/* -------------------------------------------------------------------------- */
void LifeCycleManager::shutdown_save_action(int vid, bool hard)
{
VirtualMachine * vm;
vm = vmpool->get(vid,true);
if ( vm == 0 )
{
return;
}
if (vm->get_state() == VirtualMachine::ACTIVE &&
vm->get_lcm_state() == VirtualMachine::RUNNING)
{
Nebula& nd = Nebula::instance();
VirtualMachineManager * vmm = nd.get_vmm();
//----------------------------------------------------
// SHUTDOWN_SAVE STATE
//----------------------------------------------------
vm->set_state(VirtualMachine::SHUTDOWN_SAVE);
vm->set_resched(false);
vmpool->update(vm);
vm->log("LCM",Log::INFO,"New VM state is SHUTDOWN_SAVE");
//----------------------------------------------------
if (hard)
{
vmm->trigger(VirtualMachineManager::CANCEL,vid);
}
else
{
vmm->trigger(VirtualMachineManager::SHUTDOWN,vid);
}
}
else
{
vm->log("LCM", Log::ERROR, "shutdown_save_action, VM in a wrong state.");
}
vm->unlock();
return;
}
/* -------------------------------------------------------------------------- */
/* -------------------------------------------------------------------------- */

View File

@ -232,6 +232,14 @@ void LifeCycleManager::trigger(Actions action, int _vid)
aname = "SHUTDOWN";
break;
case SHUTDOWN_SAVE:
aname = "SHUTDOWN_SAVE";
break;
case SHUTDOWN_SAVE_HARD:
aname = "SHUTDOWN_SAVE_HARD";
break;
case RESTART:
aname = "RESTART";
break;
@ -441,6 +449,14 @@ void LifeCycleManager::do_action(const string &action, void * arg)
{
shutdown_action(vid);
}
else if (action == "SHUTDOWN_SAVE")
{
shutdown_save_action(vid, false);
}
else if (action == "SHUTDOWN_SAVE_HARD")
{
shutdown_save_action(vid, true);
}
else if (action == "RESTART")
{
restart_action(vid);

View File

@ -514,6 +514,32 @@ void LifeCycleManager::shutdown_success_action(int vid)
dm->trigger(DispatchManager::POWEROFF_SUCCESS,vid);
}
else if (vm->get_lcm_state() == VirtualMachine::SHUTDOWN_SAVE)
{
//----------------------------------------------------
// EPILOG_SHUTDOWN_SAVE STATE
//----------------------------------------------------
vm->set_state(VirtualMachine::EPILOG_SHUTDOWN_SAVE);
vm->delete_snapshots();
vmpool->update(vm);
vm->set_epilog_stime(the_time);
vm->set_running_etime(the_time);
vm->set_reason(History::STOP_RESUME);
vmpool->update_history(vm);
vm->log("LCM", Log::INFO, "New VM state is EPILOG_SHUTDOWN_SAVE");
//----------------------------------------------------
tm->trigger(TransferManager::EPILOG_STOP,vid);
}
else
{
vm->log("LCM",Log::ERROR,"shutdown_success_action, VM in a wrong state");
@ -540,7 +566,8 @@ void LifeCycleManager::shutdown_failure_action(int vid)
}
if ( vm->get_lcm_state() == VirtualMachine::SHUTDOWN ||
vm->get_lcm_state() == VirtualMachine::SHUTDOWN_POWEROFF )
vm->get_lcm_state() == VirtualMachine::SHUTDOWN_POWEROFF ||
vm->get_lcm_state() == VirtualMachine::SHUTDOWN_SAVE )
{
//----------------------------------------------------
// RUNNING STATE FROM SHUTDOWN
@ -734,6 +761,10 @@ void LifeCycleManager::epilog_success_action(int vid)
{
action = DispatchManager::STOP_SUCCESS;
}
else if ( state == VirtualMachine::EPILOG_SHUTDOWN_SAVE )
{
action = DispatchManager::SHUTDOWN_SAVE_SUCCESS;
}
else if ( state == VirtualMachine::EPILOG )
{
action = DispatchManager::DONE;
@ -834,6 +865,7 @@ void LifeCycleManager::epilog_failure_action(int vid)
dm->trigger(DispatchManager::RESUBMIT, vid);
}
else if ( vm->get_lcm_state() == VirtualMachine::EPILOG_STOP ||
vm->get_lcm_state() == VirtualMachine::EPILOG_SHUTDOWN_SAVE ||
vm->get_lcm_state() == VirtualMachine::EPILOG )
{
vm->set_epilog_etime(the_time);
@ -893,6 +925,32 @@ void LifeCycleManager::cancel_success_action(int vid)
tm->trigger(TransferManager::EPILOG,vid);
}
else if (vm->get_lcm_state() == VirtualMachine::SHUTDOWN_SAVE)
{
//----------------------------------------------------
// EPILOG_SHUTDOWN_SAVE STATE
//----------------------------------------------------
vm->set_state(VirtualMachine::EPILOG_SHUTDOWN_SAVE);
vm->delete_snapshots();
vmpool->update(vm);
vm->set_epilog_stime(the_time);
vm->set_running_etime(the_time);
vm->set_reason(History::STOP_RESUME);
vmpool->update_history(vm);
vm->log("LCM", Log::INFO, "New VM state is EPILOG_SHUTDOWN_SAVE");
//----------------------------------------------------
tm->trigger(TransferManager::EPILOG_STOP,vid);
}
else
{
vm->log("LCM",Log::ERROR,"cancel_success_action, VM in a wrong state");
@ -918,7 +976,8 @@ void LifeCycleManager::cancel_failure_action(int vid)
return;
}
if ( vm->get_lcm_state() == VirtualMachine::CANCEL )
if ( vm->get_lcm_state() == VirtualMachine::CANCEL ||
vm->get_lcm_state() == VirtualMachine::SHUTDOWN_SAVE )
{
//----------------------------------------------------
// RUNNING STATE FROM CANCEL

View File

@ -381,6 +381,14 @@ void VirtualMachineAction::request_execute(xmlrpc_c::paramList const& paramList,
{
rc = dm->poweroff(id);
}
else if (action == "shutdown-save")
{
rc = dm->shutdown_save(id, false);
}
else if (action == "shutdown-save-hard")
{
rc = dm->shutdown_save(id, true);
}
switch (rc)
{
@ -1246,6 +1254,7 @@ void VirtualMachineResize::request_execute(xmlrpc_c::paramList const& paramList,
case VirtualMachine::PENDING:
case VirtualMachine::HOLD:
case VirtualMachine::FAILED:
case VirtualMachine::SHUTDOWN_SAVED:
break;
case VirtualMachine::STOPPED:
@ -1423,6 +1432,7 @@ void VirtualMachineResize::request_execute(xmlrpc_c::paramList const& paramList,
case VirtualMachine::HOLD:
case VirtualMachine::FAILED:
case VirtualMachine::POWEROFF:
case VirtualMachine::SHUTDOWN_SAVED:
ret = vm->resize(ncpu, nmemory, nvcpu, error_str);
if (ret != 0)

View File

@ -127,6 +127,7 @@ void TransferManagerDriver::protocol(
case VirtualMachine::EPILOG:
case VirtualMachine::EPILOG_STOP:
case VirtualMachine::EPILOG_SHUTDOWN_SAVE:
case VirtualMachine::CLEANUP_RESUBMIT:
lcm_action = LifeCycleManager::EPILOG_SUCCESS;
break;
@ -170,6 +171,7 @@ void TransferManagerDriver::protocol(
case VirtualMachine::EPILOG:
case VirtualMachine::EPILOG_STOP:
case VirtualMachine::EPILOG_SHUTDOWN_SAVE:
case VirtualMachine::CLEANUP_RESUBMIT:
lcm_action = LifeCycleManager::EPILOG_FAILURE;
break;

View File

@ -902,7 +902,8 @@ error_driver:
os << "cancel_action, error getting driver " << vm->get_vmm_mad();
error_common:
if ( vm->get_lcm_state() == VirtualMachine::CANCEL ) //not in DELETE
if ( vm->get_lcm_state() == VirtualMachine::CANCEL ||
vm->get_lcm_state() == VirtualMachine::SHUTDOWN_SAVE ) //not in DELETE
{
Nebula &ne = Nebula::instance();
LifeCycleManager * lcm = ne.get_lcm();