From 1995b7a14ce1a1ca446a9031a0c2011fe47c15da Mon Sep 17 00:00:00 2001 From: "Ruben S. Montero" Date: Fri, 1 Feb 2013 02:23:01 +0100 Subject: [PATCH] feature #846: Add more message types. Template is loaded in the VirtualMachineXML object. OpenNebula API calls are always made through VirtualMachinePoolXML. --- src/scheduler/include/VirtualMachinePoolXML.h | 20 ++- src/scheduler/include/VirtualMachineXML.h | 54 ++++---- .../src/pool/VirtualMachinePoolXML.cc | 42 +++++- src/scheduler/src/pool/VirtualMachineXML.cc | 126 ++++++------------ src/scheduler/src/sched/Scheduler.cc | 53 +++++--- src/scheduler/src/sched/SchedulerTemplate.cc | 12 +- 6 files changed, 166 insertions(+), 141 deletions(-) diff --git a/src/scheduler/include/VirtualMachinePoolXML.h b/src/scheduler/include/VirtualMachinePoolXML.h index 08cf34e4e1..02f3ac8989 100644 --- a/src/scheduler/include/VirtualMachinePoolXML.h +++ b/src/scheduler/include/VirtualMachinePoolXML.h @@ -58,10 +58,28 @@ public: * Dispatch a VM to the given host * @param vid the VM id * @param hid the id of the target host - * @param resched the machine is going to be rescheduled + * @param resched the machine is going to be rescheduled */ int dispatch(int vid, int hid, bool resched) const; + /** + * Update the VM template + * @param vid the VM id + * @param st the template string + */ + int update(int vid, const string &st) const; + + /** + * Update the VM template + * @param the VM + */ + int update(VirtualMachineXML * vm) const + { + string xml; + + return update(vm->get_oid(), vm->get_template(xml)); + }; + protected: int get_suitable_nodes(vector& content) diff --git a/src/scheduler/include/VirtualMachineXML.h b/src/scheduler/include/VirtualMachineXML.h index 84f7726c38..3261d4a012 100644 --- a/src/scheduler/include/VirtualMachineXML.h +++ b/src/scheduler/include/VirtualMachineXML.h @@ -22,6 +22,7 @@ #include "ObjectXML.h" #include "HostPoolXML.h" +#include "VirtualMachineTemplate.h" using namespace std; @@ -29,16 +30,14 @@ class VirtualMachineXML : public ObjectXML { public: - VirtualMachineXML(Client * client, const string &xml_doc): - ObjectXML(xml_doc), - client(client) + VirtualMachineXML(const string &xml_doc): + ObjectXML(xml_doc) { init_attributes(); }; - VirtualMachineXML(Client * client, const xmlNodePtr node): - ObjectXML(node), - client(client) + VirtualMachineXML(const xmlNodePtr node): + ObjectXML(node) { init_attributes(); } @@ -107,6 +106,24 @@ public: return requirements; }; + /** + * Get the user template of the VM + * @return the template as a XML string + */ + string& get_template(string& xml_str) + { + if (vm_template != 0) + { + vm_template->to_xml(xml_str); + } + else + { + xml_str = ""; + } + + return xml_str; + } + /** * Function to write a Virtual Machine in an output stream */ @@ -134,28 +151,11 @@ public: }; /** - * Adds a message to the VM's USER_TEMPLATE/SCHEDULER_MESSAGE attribute - * @param st Message to set + * Adds a message to the VM's USER_TEMPLATE/SCHED_MESSAGE attribute + * @param st Message to set */ void log(const string &st); - /** - * Clears the VM's USER_TEMPLATE/SCHEDULER_MESSAGE attribute - */ - void clear_log() - { - log(""); - }; - - /** - * Replaces the VM USER_TEMPLATE contents - * - * @param st New template contents - * - * @return 0 on success, -1 otherwise - */ - int update(const string &st); - protected: /** @@ -213,9 +213,9 @@ protected: vector hosts; /** - * XML-RPC client + * The VM user template */ - Client * client; + VirtualMachineTemplate * vm_template; }; #endif /* VM_XML_H_ */ diff --git a/src/scheduler/src/pool/VirtualMachinePoolXML.cc b/src/scheduler/src/pool/VirtualMachinePoolXML.cc index 7a75605283..c48b131e82 100644 --- a/src/scheduler/src/pool/VirtualMachinePoolXML.cc +++ b/src/scheduler/src/pool/VirtualMachinePoolXML.cc @@ -59,7 +59,7 @@ void VirtualMachinePoolXML::add_object(xmlNodePtr node) return; } - VirtualMachineXML* vm = new VirtualMachineXML(client, node); + VirtualMachineXML* vm = new VirtualMachineXML(node); objects.insert(pair(vm->get_oid(),vm)); } @@ -96,7 +96,6 @@ int VirtualMachinePoolXML::load_info(xmlrpc_c::value &result) /* -------------------------------------------------------------------------- */ /* -------------------------------------------------------------------------- */ - int VirtualMachinePoolXML::dispatch(int vid, int hid, bool resched) const { ostringstream oss; @@ -108,7 +107,7 @@ int VirtualMachinePoolXML::dispatch(int vid, int hid, bool resched) const } else { - oss << "Dispatching "; + oss << "Dispatching "; } oss << "virtual machine " << vid << " to host " << hid; @@ -173,3 +172,40 @@ int VirtualMachinePoolXML::dispatch(int vid, int hid, bool resched) const return 0; } + +/* -------------------------------------------------------------------------- */ +/* -------------------------------------------------------------------------- */ + +int VirtualMachinePoolXML::update(int vid, const string &st) const +{ + xmlrpc_c::value result; + bool success; + + try + { + client->call( client->get_endpoint(), // serverUrl + "one.vm.update", // methodName + "sis", // arguments format + &result, // resultP + client->get_oneauth().c_str(), // argument + vid, // VM ID + st.c_str() // Template + ); + } + catch (exception const& e) + { + return -1; + } + + vector values = + xmlrpc_c::value_array(result).vectorValueValue(); + + success = xmlrpc_c::value_boolean(values[0]); + + if (!success) + { + return -1; + } + + return 0; +} diff --git a/src/scheduler/src/pool/VirtualMachineXML.cc b/src/scheduler/src/pool/VirtualMachineXML.cc index 16372d9706..fd4d3561a0 100644 --- a/src/scheduler/src/pool/VirtualMachineXML.cc +++ b/src/scheduler/src/pool/VirtualMachineXML.cc @@ -17,17 +17,18 @@ #include #include "VirtualMachineXML.h" -#include "VirtualMachineTemplate.h" void VirtualMachineXML::init_attributes() { - vector result; + vector result; + vector nodes; oid = atoi(((*this)["/VM/ID"] )[0].c_str()); uid = atoi(((*this)["/VM/UID"])[0].c_str()); gid = atoi(((*this)["/VM/GID"])[0].c_str()); result = ((*this)["/VM/TEMPLATE/MEMORY"]); + if (result.size() > 0) { memory = atoi(result[0].c_str()); @@ -38,6 +39,7 @@ void VirtualMachineXML::init_attributes() } result = ((*this)["/VM/TEMPLATE/CPU"]); + if (result.size() > 0) { istringstream iss; @@ -50,6 +52,7 @@ void VirtualMachineXML::init_attributes() } result = ((*this)["/VM/TEMPLATE/RANK"]); + if (result.size() > 0) { rank = result[0]; @@ -60,6 +63,7 @@ void VirtualMachineXML::init_attributes() } result = ((*this)["/VM/TEMPLATE/REQUIREMENTS"]); + if (result.size() > 0) { requirements = result[0]; @@ -67,11 +71,11 @@ void VirtualMachineXML::init_attributes() else { requirements = ""; - } + } result = ((*this)["/VM/HISTORY_RECORDS/HISTORY/HID"]); - if (result.size() > 0) + if (result.size() > 0) { hid = atoi(result[0].c_str()); } @@ -89,7 +93,20 @@ void VirtualMachineXML::init_attributes() else { resched = 0; - } + } + + if (get_nodes("/VM/USER_TEMPLATE", nodes) > 0) + { + vm_template = new VirtualMachineTemplate; + + vm_template->from_xml_node(nodes[0]); + + free_nodes(nodes); + } + else + { + vm_template = 0; + } } /* -------------------------------------------------------------------------- */ @@ -105,6 +122,11 @@ VirtualMachineXML::~VirtualMachineXML() } hosts.clear(); + + if (vm_template != 0) + { + delete vm_template; + } } /* -------------------------------------------------------------------------- */ @@ -118,7 +140,7 @@ void VirtualMachineXML::add_host(int host_id) ss = new VirtualMachineXML::Host(host_id); - hosts.push_back(ss); + hosts.push_back(ss); } } @@ -229,95 +251,25 @@ void VirtualMachineXML::get_requirements (int& cpu, int& memory, int& disk) void VirtualMachineXML::log(const string &st) { - vector nodes; - - ostringstream oss; - string xml_st; - - int rc = get_nodes("/VM/USER_TEMPLATE", nodes); - - if (rc > 0) + if (vm_template == 0 || st.empty()) { - VirtualMachineTemplate vm_template; - vm_template.from_xml_node(nodes[0]); + return; + } - free_nodes(nodes); + char str[26]; + time_t the_time = time(NULL); - if (!st.empty()) - { - char str[26]; - - time_t the_time = time(NULL); + ostringstream oss; #ifdef SOLARIS - ctime_r(&(the_time),str,sizeof(char)*26); + ctime_r(&(the_time),str,sizeof(char)*26); #else - ctime_r(&(the_time),str); + ctime_r(&(the_time),str); #endif - // Get rid of final enter character - str[24] = '\0'; - oss << str << ": " << st; + str[24] = '\0'; // Get rid of final enter character - vm_template.replace("SCHEDULER_MESSAGE", oss.str()); + oss << str << " : " << st; - update(vm_template.to_xml(xml_st)); - } - else - { - vector attr; - int num = vm_template.remove("SCHEDULER_MESSAGE", attr); - - for (int i = 0; i < num ; i++) - { - if (attr[i] != 0) - { - delete attr[i]; - } - } - - if (num > 0) - { - update(vm_template.to_xml(xml_st)); - } - } - } + vm_template->replace("SCHED_MESSAGE", oss.str()); } - -/* -------------------------------------------------------------------------- */ -/* -------------------------------------------------------------------------- */ - -int VirtualMachineXML::update(const string &st) -{ - xmlrpc_c::value result; - bool success; - - try - { - client->call( client->get_endpoint(), // serverUrl - "one.vm.update", // methodName - "sis", // arguments format - &result, // resultP - client->get_oneauth().c_str(), // argument - oid, - st.c_str() - ); - } - catch (exception const& e) - { - return -1; - } - - vector values = - xmlrpc_c::value_array(result).vectorValueValue(); - - success = xmlrpc_c::value_boolean( values[0] ); - - if (!success) - { - return -1; - } - - return 0; -} - diff --git a/src/scheduler/src/sched/Scheduler.cc b/src/scheduler/src/sched/Scheduler.cc index c9f16afe4d..87474a7e8a 100644 --- a/src/scheduler/src/sched/Scheduler.cc +++ b/src/scheduler/src/sched/Scheduler.cc @@ -128,7 +128,7 @@ void Scheduler::start() conf.get("ONED_PORT", oned_port); oss.str(""); - oss << "http://localhost:" << oned_port << "/RPC2"; + oss << "http://localhost:" << oned_port << "/RPC2"; url = oss.str(); conf.get("SCHED_INTERVAL", timer); @@ -142,9 +142,9 @@ void Scheduler::start() conf.get("LIVE_RESCHEDS", live_rescheds); conf.get("HYPERVISOR_MEM", hypervisor_mem); - + oss.str(""); - + oss << "Starting Scheduler Daemon" << endl; oss << "----------------------------------------\n"; oss << " Scheduler Configuration File \n"; @@ -176,7 +176,7 @@ void Scheduler::start() hpool = new HostPoolXML(client, hypervisor_mem); clpool = new ClusterPoolXML(client); - vmpool = new VirtualMachinePoolXML(client, + vmpool = new VirtualMachinePoolXML(client, machines_limit, (live_rescheds == 1)); acls = new AclXML(client); @@ -340,7 +340,8 @@ void Scheduler::match() int gid; int n_hosts; int n_matched; - bool req_error; + int n_auth; + int n_error; string reqs; @@ -368,7 +369,8 @@ void Scheduler::match() n_hosts = 0; n_matched = 0; - req_error = false; + n_auth = 0; + n_error = 0; for (h_it=hosts.begin(), matched=false; h_it != hosts.end(); h_it++) { @@ -410,6 +412,8 @@ void Scheduler::match() continue; } + n_auth++; + // ----------------------------------------------------------------- // Evaluate VM requirements // ----------------------------------------------------------------- @@ -424,7 +428,7 @@ void Scheduler::match() ostringstream error_msg; matched = false; - req_error = true; + n_error++; error_msg << "Error evaluating REQUIREMENTS expression: '" << reqs << "', error: " << error; @@ -443,7 +447,7 @@ void Scheduler::match() { matched = true; } - + if ( matched == false ) { ostringstream oss; @@ -480,16 +484,33 @@ void Scheduler::match() } } - if (n_hosts == 0 && !req_error) + // --------------------------------------------------------------------- + // Log scheduling errors to VM user if any + // --------------------------------------------------------------------- + + if (n_hosts == 0) //No hosts assigned, let's see why { - if (n_matched == 0) + if (n_error == 0) //No syntax error { - vm->log("The Scheduler could not find any Host that meets the requirements expression"); - } - else - { - vm->log("The Scheduler could not find any Host with enough capacity to deploy the VM"); + if (hosts.size() == 0) + { + vm->log("No hosts enabled to run VMs"); + } + else if (n_auth == 0) + { + vm->log("User is not authorized to use any host"); + } + else if (n_matched == 0) + { + vm->log("No host meets the REQUIREMENTS expression"); + } + else + { + vm->log("No host with enough capacity to deploy the VM"); + } } + + vmpool->update(vm); } } } @@ -591,8 +612,6 @@ void Scheduler::dispatch() { rc = vmpool->dispatch(vm_it->first, hid, vm->is_resched()); - vm->clear_log(); - if (rc == 0 && !vm->is_resched()) { dispatched_vms++; diff --git a/src/scheduler/src/sched/SchedulerTemplate.cc b/src/scheduler/src/sched/SchedulerTemplate.cc index 51747ee603..e8e6d1bf01 100644 --- a/src/scheduler/src/sched/SchedulerTemplate.cc +++ b/src/scheduler/src/sched/SchedulerTemplate.cc @@ -73,19 +73,19 @@ void SchedulerTemplate::set_conf_default() attribute = new SingleAttribute("MAX_HOST",value); conf_default.insert(make_pair(attribute->name(),attribute)); - + //LIVE_RESCHEDS value = "0"; attribute = new SingleAttribute("LIVE_RESCHEDS",value); conf_default.insert(make_pair(attribute->name(),attribute)); - //DEFAULT_SCHED + //DEFAULT_SCHED map vvalue; vvalue.insert(make_pair("POLICY","1")); vattribute = new VectorAttribute("DEFAULT_SCHED",vvalue); - conf_default.insert(make_pair(attribute->name(),vattribute)); + conf_default.insert(make_pair(vattribute->name(),vattribute)); //HYPERVISOR_MEM value = "0.1"; @@ -105,7 +105,7 @@ string SchedulerTemplate::get_policy() const istringstream iss; vector vsched; - const VectorAttribute * sched; + const VectorAttribute * sched; get("DEFAULT_SCHED", vsched); @@ -123,7 +123,7 @@ string SchedulerTemplate::get_policy() const case 1: //Striping rank = "- RUNNING_VMS"; break; - + case 2: //Load-aware rank = "FREE_CPU"; break; @@ -137,4 +137,4 @@ string SchedulerTemplate::get_policy() const } return rank; -} \ No newline at end of file +}