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

feature #1483: Add a separated action VM pool

This commit is contained in:
Ruben S. Montero 2013-02-07 00:14:25 +01:00
parent 59f4331b05
commit 2391713df0
7 changed files with 190 additions and 173 deletions

View File

@ -19,23 +19,21 @@
#include <string>
using namespace std;
namespace one_util
{
string& toupper(string& st)
inline string& toupper(string& st)
{
transform(st.begin(),st.end(),st.begin(),(int(*)(int))std::toupper);
return st;
};
string& tolower(string& st)
inline string& tolower(string& st)
{
transform(st.begin(),st.end(),st.begin(),(int(*)(int))std::tolower);
return st;
};
string log_time(time_t the_time)
inline string log_time(time_t the_time)
{
char time_str[26];
@ -50,11 +48,10 @@ namespace one_util
return string(time_str);
};
string log_time()
inline string log_time()
{
return log_time( time(0) );
};
}
};
#endif /* UTIL_H_ */

View File

@ -50,6 +50,7 @@ protected:
hpool(0),
clpool(0),
vmpool(0),
vmapool(0),
acls(0),
timer(0),
url(""),
@ -79,6 +80,11 @@ protected:
delete vmpool;
}
if ( vmapool != 0)
{
delete vmapool;
}
if ( acls != 0)
{
delete acls;
@ -94,11 +100,13 @@ protected:
// Pools
// ---------------------------------------------------------------
HostPoolXML * hpool;
ClusterPoolXML * clpool;
VirtualMachinePoolXML * vmpool;
HostPoolXML * hpool;
ClusterPoolXML * clpool;
AclXML * acls;
VirtualMachinePoolXML * vmpool;
VirtualMachineActionsPoolXML* vmapool;
AclXML * acls;
// ---------------------------------------------------------------
// Scheduler Policies
@ -134,7 +142,7 @@ protected:
virtual int set_up_pools();
virtual int scheduled_actions();
virtual int do_scheduled_actions();
private:
Scheduler(Scheduler const&){};
@ -143,7 +151,6 @@ private:
friend void * scheduler_action_loop(void *arg);
// ---------------------------------------------------------------
// Scheduling Policies
// ---------------------------------------------------------------

View File

@ -32,7 +32,7 @@ public:
bool _live_resched):
PoolXML(client, machines_limit), live_resched(_live_resched){};
~VirtualMachinePoolXML(){};
virtual ~VirtualMachinePoolXML(){};
/**
* Retrieves the pending and rescheduling VMs
@ -43,15 +43,6 @@ public:
*/
int set_up();
/**
* Retrieves the VMs with scheduled actions
*
* @return 0 on success
* -1 on error
* -2 if no VMs need to be scheduled
*/
int set_up_actions();
/**
* Gets an object from the pool
* @param oid the object unique identifier
@ -93,6 +84,46 @@ public:
return update(vm->get_oid(), vm->get_template(xml));
};
protected:
int get_suitable_nodes(vector<xmlNodePtr>& content)
{
return get_nodes("/VM_POOL/VM[STATE=1 or (LCM_STATE=3 and RESCHED=1)]",
content);
}
virtual void add_object(xmlNodePtr node);
virtual int load_info(xmlrpc_c::value &result);
/**
* Do live migrations to resched VMs
*/
bool live_resched;
};
/* -------------------------------------------------------------------------- */
/* -------------------------------------------------------------------------- */
class VirtualMachineActionsPoolXML : public VirtualMachinePoolXML
{
public:
VirtualMachineActionsPoolXML(Client* client,
unsigned int machines_limit):
VirtualMachinePoolXML(client, machines_limit, false){};
virtual ~VirtualMachineActionsPoolXML(){};
/**
* Retrieves the VMs with pending actions
*
* @return 0 on success
* -1 on error
* -2 if no VMs with pending actions
*/
int set_up();
/**
* Calls one.vm.action
*
@ -106,22 +137,15 @@ public:
protected:
int get_suitable_nodes(vector<xmlNodePtr>& content);
int get_suitable_nodes(vector<xmlNodePtr>& content)
{
ostringstream oss;
virtual void add_object(xmlNodePtr node);
oss << "/VM_POOL/VM/USER_TEMPLATE/SCHED_ACTION[TIME < " << time(0)
<< " and not(DONE > 0)]/../..";
virtual int load_info(xmlrpc_c::value &result);
/**
* Do live migrations to resched VMs
*/
bool live_resched;
/**
* True to retrieve pending/resched VMs, false to get VMs with scheduled
* actions
*/
bool retrieve_pending;
return get_nodes(oss.str().c_str(), content);
}
};
#endif /* VM_POOL_XML_H_ */

View File

@ -125,14 +125,35 @@ public:
}
/**
* Returns a the VM Template
* Returns the scheduled actions of the VM
*
* @return A pointer to the VM Template (not to a copy)
* @param attributes to hold the VM actions
*/
VirtualMachineTemplate* get_template()
void get_actions(vector<Attribute *>& attributes) const
{
return vm_template;
};
attributes.clear();
vm_template->remove("SCHED_ACTION", attributes);
}
/**
* Sets an attribute in the VM Template, it must be allocated in the heap
*
* @param attributes to hold the VM actions
*/
void set_attribute(Attribute* att)
{
return vm_template->set(att);
}
/**
* Checks the action to be performed and returns the corresponding XML-RPC
* method name.
* @param action_st, the action to be performed. The XML-RPC name is
* returned here
* @return 0 on success.
*/
static int parse_action_name(string& action_st);
/**
* Function to write a Virtual Machine in an output stream

View File

@ -22,8 +22,6 @@ int VirtualMachinePoolXML::set_up()
ostringstream oss;
int rc;
retrieve_pending = true;
rc = PoolXML::set_up();
if ( rc == 0 )
@ -52,63 +50,6 @@ int VirtualMachinePoolXML::set_up()
/* -------------------------------------------------------------------------- */
/* -------------------------------------------------------------------------- */
int VirtualMachinePoolXML::set_up_actions()
{
ostringstream oss;
int rc;
retrieve_pending = false;
rc = PoolXML::set_up();
if ( rc == 0 )
{
if (objects.empty())
{
return -2;
}
oss.str("");
oss << "VMs with scheduled actions:" << endl;
map<int,ObjectXML*>::iterator it;
for (it=objects.begin();it!=objects.end();it++)
{
oss << " " << it->first;
}
NebulaLog::log("VM",Log::DEBUG,oss);
}
return rc;
}
/* -------------------------------------------------------------------------- */
/* -------------------------------------------------------------------------- */
int VirtualMachinePoolXML::get_suitable_nodes(vector<xmlNodePtr>& content)
{
if (retrieve_pending)
{
return get_nodes(
"/VM_POOL/VM[STATE=1 or (LCM_STATE=3 and RESCHED=1)]",
content);
}
ostringstream oss;
oss << "/VM_POOL/VM/USER_TEMPLATE/SCHED_ACTION[TIME < " << time(0)
<< " and not(DONE > 0)]/../..";
return get_nodes(
oss.str().c_str(),
content);
}
/* -------------------------------------------------------------------------- */
/* -------------------------------------------------------------------------- */
void VirtualMachinePoolXML::add_object(xmlNodePtr node)
{
if ( node == 0 || node->children == 0 || node->children->next==0 )
@ -268,11 +209,42 @@ int VirtualMachinePoolXML::update(int vid, const string &st) const
return 0;
}
/* -------------------------------------------------------------------------- */
/* -------------------------------------------------------------------------- */
int VirtualMachinePoolXML::action(
int VirtualMachineActionsPoolXML::set_up()
{
ostringstream oss;
int rc;
rc = PoolXML::set_up();
if ( rc == 0 )
{
if (objects.empty())
{
return -2;
}
oss.str("");
oss << "VMs with scheduled actions:" << endl;
map<int,ObjectXML*>::iterator it;
for (it=objects.begin();it!=objects.end();it++)
{
oss << " " << it->first;
}
NebulaLog::log("VM",Log::DEBUG,oss);
}
return rc;
}
/* -------------------------------------------------------------------------- */
/* -------------------------------------------------------------------------- */
int VirtualMachineActionsPoolXML::action(
int vid,
const string& action,
string& error_msg) const

View File

@ -17,6 +17,7 @@
#include <algorithm>
#include "VirtualMachineXML.h"
#include "Util.h"
void VirtualMachineXML::init_attributes()
{
@ -265,21 +266,42 @@ void VirtualMachineXML::log(const string &st)
{
return;
}
ostringstream oss;
char str[26];
time_t the_time = time(NULL);
ostringstream oss;
#ifdef SOLARIS
ctime_r(&(the_time),str,sizeof(char)*26);
#else
ctime_r(&(the_time),str);
#endif
str[24] = '\0'; // Get rid of final enter character
oss << str << " : " << st;
oss << one_util::log_time(time(0)) << " : " << st;
vm_template->replace("SCHED_MESSAGE", oss.str());
}
/* -------------------------------------------------------------------------- */
/* -------------------------------------------------------------------------- */
int VirtualMachineXML::parse_action_name(string& action_st)
{
one_util::tolower(action_st);
// onevm delete command uses the xml-rpc finalize action
if (action_st == "delete")
{
action_st = "finalize";
}
if ( action_st != "shutdown"
&& action_st != "hold"
&& action_st != "release"
&& action_st != "stop"
&& action_st != "cancel"
&& action_st != "suspend"
&& action_st != "resume"
&& action_st != "restart"
&& action_st != "resubmit"
&& action_st != "reboot"
&& action_st != "reset"
&& action_st != "poweroff"
&& action_st != "finalize")
{
return -1;
}
return 0;
};

View File

@ -180,6 +180,8 @@ void Scheduler::start()
vmpool = new VirtualMachinePoolXML(client,
machines_limit,
(live_rescheds == 1));
vmapool= new VirtualMachineActionsPoolXML(client, machines_limit);
acls = new AclXML(client);
// -----------------------------------------------------------
@ -624,20 +626,11 @@ void Scheduler::dispatch()
/* -------------------------------------------------------------------------- */
/* -------------------------------------------------------------------------- */
int Scheduler::scheduled_actions()
int Scheduler::do_scheduled_actions()
{
int rc = vmpool->set_up_actions();
if ( rc != 0 )
{
return rc;
}
VirtualMachineXML* vm;
VirtualMachineTemplate* vm_template;
vector<string> v_st;
const map<int, ObjectXML*> vms = vmapool->get_objects();
map<int, ObjectXML*>::const_iterator vm_it;
vector<Attribute *> attributes;
@ -645,28 +638,23 @@ int Scheduler::scheduled_actions()
VectorAttribute* vatt;
time_t the_time = time(0);
int action_time;
int done_time;
int has_time;
int has_done;
int action_time, done_time, has_time, has_done;
string action_st, error_msg;
ostringstream oss;
ostringstream oss_aux;
time_t the_time = time(0);
string time_str = one_util::log_time(the_time);
const map<int, ObjectXML*> vms = vmpool->get_objects();
for (vm_it=vms.begin(); vm_it != vms.end(); vm_it++)
{
vm = static_cast<VirtualMachineXML*>(vm_it->second);
vm_template = vm->get_template();
attributes.clear();
vm_template->remove("SCHED_ACTION", attributes);
vm->get_actions(attributes);
// TODO: Sort actions by TIME
for (it=attributes.begin(); it != attributes.end(); it++)
{
vatt = dynamic_cast<VectorAttribute*>(*it);
@ -676,46 +664,26 @@ int Scheduler::scheduled_actions()
continue;
}
has_time = vatt->vector_value("TIME", action_time);
has_done = vatt->vector_value("DONE", done_time);
has_time = vatt->vector_value("TIME", action_time);
has_done = vatt->vector_value("DONE", done_time);
action_st = vatt->vector_value("ACTION");
one_util::tolower(action_st);
if (has_time == 0 && has_done == -1 && action_time < the_time)
{
oss.str("");
ostringstream oss;
// onevm delete command uses the xml-rpc finalize action
if (action_st == "delete")
{
action_st = "finalize";
}
int rc = VirtualMachineXML::parse_action_name(action_st);
oss << "Executing action '" << action_st << "' for VM "
<< vm->get_oid() << " : ";
if ( action_st != "shutdown"
&& action_st != "hold"
&& action_st != "release"
&& action_st != "stop"
&& action_st != "cancel"
&& action_st != "suspend"
&& action_st != "resume"
&& action_st != "restart"
&& action_st != "resubmit"
&& action_st != "reboot"
&& action_st != "reset"
&& action_st != "poweroff"
&& action_st != "finalize")
if ( rc != 0 )
{
error_msg = "This action is not supported.";
rc = -1;
}
else
{
rc = vmpool->action(vm->get_oid(), action_st, error_msg);
rc = vmapool->action(vm->get_oid(), action_st, error_msg);
}
if (rc == 0)
@ -727,7 +695,8 @@ int Scheduler::scheduled_actions()
}
else
{
oss_aux.str("");
ostringstream oss_aux;
oss_aux << time_str << " : " << error_msg;
vatt->replace("MESSAGE", oss_aux.str());
@ -735,13 +704,13 @@ int Scheduler::scheduled_actions()
oss << "Failure. " << error_msg;
}
NebulaLog::log("VM",Log::INFO,oss);
NebulaLog::log("VM", Log::INFO, oss);
vm->set_attribute(vatt);
vmpool->update(vm);
}
vm_template->set(vatt);
}
vmpool->update(vm);
}
return 0;
@ -756,7 +725,12 @@ void Scheduler::do_action(const string &name, void *args)
if (name == ACTION_TIMER)
{
scheduled_actions();
rc = vmapool->set_up();
if ( rc == 0 )
{
do_scheduled_actions();
}
rc = set_up_pools();