diff --git a/include/VMGroupRole.h b/include/VMGroupRole.h index 4928acbc42..c57c007f66 100644 --- a/include/VMGroupRole.h +++ b/include/VMGroupRole.h @@ -108,12 +108,20 @@ public: /* Placement constraints */ /* ---------------------------------------------------------------------- */ /** - * Generates a string with the boolean expresion to conform the role - * policy + * Generates a string with the boolean expression to conform the role + * internal policy * @param vm_id of the VM to generate the requirements for * @param requirements */ - void vm_requirements(int vm_id, std::string requirements); + void vm_role_requirements(int vm_id, std::string& requirements); + + /** + * Generates a string with the boolean expression to conform an affinity + * constraint policy + * @param policy to place VMs respect to this role VMs + * @param requirements + */ + void role_requirements(Policy policy, std::string& requirements); private: /** @@ -145,6 +153,15 @@ public: by_id.delete_roles(); }; + /* ---------------------------------------------------------------------- */ + /* ---------------------------------------------------------------------- */ + /** + * Max number of roles in a VMGroup + */ + const static int MAX_ROLES = 32; + + /* ---------------------------------------------------------------------- */ + /* ---------------------------------------------------------------------- */ /** * Function to print the VMGroupRoles into a string in XML format * @param xml the resulting XML string @@ -173,11 +190,12 @@ public: /** * Generates the ids corresponding to a set of role names - * @param keys the set of names + * @param rnames string with a comma separated list of role names * @param keyi the set of ids + * * @return 0 if all the names were successfully translated */ - int names_to_ids(const std::set keys, std::set& keyi); + int names_to_ids(const std::string& rnames, std::set& keyi); /** * Adds a VM to a role @@ -220,10 +238,60 @@ public: return by_id.get(id); } + /* ---------------------------------------------------------------------- */ + /* ---------------------------------------------------------------------- */ /** - * Max number of roles in a VMGroup + * Iterator for the roles in the group */ - const static int MAX_ROLES = 32; + class RoleIterator + { + public: + RoleIterator& operator=(const RoleIterator& rhs) + { + role_it = rhs.role_it; + return *this; + } + + RoleIterator& operator++() + { + ++role_it; + return *this; + } + + bool operator!=(const RoleIterator& rhs) + { + return role_it != rhs.role_it; + } + + VMGroupRole * operator*() const + { + return role_it->second; + } + + RoleIterator(){}; + RoleIterator(const RoleIterator& rit):role_it(rit.role_it){}; + RoleIterator(const std::map::iterator& _role_it) + :role_it(_role_it){}; + + virtual ~RoleIterator(){}; + + private: + std::map::iterator role_it; + }; + + RoleIterator begin() + { + RoleIterator it(by_id.begin()); + return it; + } + + RoleIterator end() + { + RoleIterator it(by_id.end()); + return it; + } + + typedef class RoleIterator role_iterator; private: /** @@ -308,56 +376,6 @@ private: std::map roles; }; - class RoleIterator - { - public: - RoleIterator& operator=(const RoleIterator& rhs) - { - role_it = rhs.role_it; - return *this; - } - - RoleIterator& operator++() - { - ++role_it; - return *this; - } - - bool operator!=(const RoleIterator& rhs) - { - return role_it != rhs.role_it; - } - - VMGroupRole * operator*() const - { - return role_it->second; - } - - RoleIterator(){}; - RoleIterator(const RoleIterator& rit):role_it(rit.role_it){}; - RoleIterator(const std::map::iterator& _role_it) - :role_it(_role_it){}; - - virtual ~RoleIterator(){}; - - private: - std::map::iterator role_it; - }; - - RoleIterator begin() - { - RoleIterator it(by_id.begin()); - return it; - } - - RoleIterator end() - { - RoleIterator it(by_id.end()); - return it; - } - - typedef class RoleIterator role_iterator; - /** * The role template to store the VMGroupRole */ diff --git a/src/scheduler/include/PoolXML.h b/src/scheduler/include/PoolXML.h index 70d867097c..bd4fab99d4 100644 --- a/src/scheduler/include/PoolXML.h +++ b/src/scheduler/include/PoolXML.h @@ -46,15 +46,15 @@ public: { int rc; - // ------------------------------------------------------------------------- + // --------------------------------------------------------------------- // Clean the pool to get updated data from OpenNebula - // ------------------------------------------------------------------------- + // --------------------------------------------------------------------- flush(); - // ------------------------------------------------------------------------- + // --------------------------------------------------------------------- // Load the ids (to get an updated list of the pool) - // ------------------------------------------------------------------------- + // --------------------------------------------------------------------- xmlrpc_c::value result; @@ -124,8 +124,49 @@ public: } }; -protected: + /** + * Gets an object and removes it from the pool. The calling function + * needs to free the object memory + * @param oid of the object + * + * @return pointer of the object 0 if not found + */ + virtual ObjectXML * erase(int oid) + { + map::iterator it; + it = objects.find(oid); + + if ( it == objects.end() ) + { + return 0; + } + else + { + ObjectXML * obj = it->second; + + objects.erase(it); + + return obj; + } + } + + /** + * Inserts a new object in the pool + * @param obj pointer to the XML object to be inserted + * + * @return true if the object was successfully inserted + */ + virtual bool insert(int oid, ObjectXML * obj) + { + pair::iterator, bool> rc; + + rc = objects.insert(pair(oid, obj)); + + return rc.second; + } + +protected: // ------------------------------------------------------------------------ PoolXML(Client* client, unsigned int pool_limit = 0):ObjectXML() @@ -140,7 +181,6 @@ protected: }; // ------------------------------------------------------------------------ - /** * Inserts a new ObjectXML into the objects map */ @@ -156,10 +196,24 @@ protected: */ virtual int load_info(xmlrpc_c::value &result) = 0; + /** + * Deletes pool objects and frees resources. + */ + void flush() + { + map::iterator it; + + for (it=objects.begin();it!=objects.end();it++) + { + delete it->second; + } + + objects.clear(); + } + // ------------------------------------------------------------------------ // Attributes // ------------------------------------------------------------------------ - /** * XML-RPC client */ @@ -175,23 +229,6 @@ protected: * Hash map contains the suitable [id, object] pairs. */ map objects; - - -private: - /** - * Deletes pool objects and frees resources. - */ - void flush() - { - map::iterator it; - - for (it=objects.begin();it!=objects.end();it++) - { - delete it->second; - } - - objects.clear(); - } }; #endif /* POOL_XML_H_ */ diff --git a/src/scheduler/include/Scheduler.h b/src/scheduler/include/Scheduler.h index 88fea7f65f..35165e16df 100644 --- a/src/scheduler/include/Scheduler.h +++ b/src/scheduler/include/Scheduler.h @@ -50,15 +50,16 @@ public: protected: Scheduler(): + acls(0), + upool(0), hpool(0), clpool(0), - vmpool(0), - vmapool(0), dspool(0), img_dspool(0), - upool(0), + vmpool(0), + vm_roles_pool(0), vmgpool(0), - acls(0), + vmapool(0), timer(0), one_xmlrpc(""), machines_limit(0), @@ -74,6 +75,7 @@ protected: delete clpool; delete vmpool; + delete vm_roles_pool; delete vmapool; delete dspool; @@ -88,19 +90,21 @@ protected: // --------------------------------------------------------------- // Pools // --------------------------------------------------------------- + AclXML * acls; + UserPoolXML * upool; HostPoolXML * hpool; ClusterPoolXML * clpool; - VirtualMachinePoolXML * vmpool; - VirtualMachineActionsPoolXML* vmapool; SystemDatastorePoolXML * dspool; - ImageDatastorePoolXML * img_dspool; - UserPoolXML * upool; + ImageDatastorePoolXML * img_dspool; + + VirtualMachinePoolXML * vmpool; + VirtualMachinePoolXML * vm_roles_pool; VMGroupPoolXML * vmgpool; - AclXML * acls; + VirtualMachineActionsPoolXML* vmapool; // --------------------------------------------------------------- // Scheduler Policies diff --git a/src/scheduler/include/VMGroupXML.h b/src/scheduler/include/VMGroupXML.h index 5ce001f1d2..e0f834f5c8 100644 --- a/src/scheduler/include/VMGroupXML.h +++ b/src/scheduler/include/VMGroupXML.h @@ -19,6 +19,7 @@ #include "ObjectXML.h" #include "VMGroupRole.h" +#include "VMGroupRule.h" class VMGroupXML : public ObjectXML { @@ -39,10 +40,17 @@ public: }; private: + // ------------------------------------------------------------------------ + // VMGroup Attributes + // ------------------------------------------------------------------------ int oid; + std::string name; + VMGroupRoles roles; + VMGroupRule::rule_set rules; + void init_attributes(); }; diff --git a/src/scheduler/include/VirtualMachinePoolXML.h b/src/scheduler/include/VirtualMachinePoolXML.h index e73a806bdb..1001fa8eb2 100644 --- a/src/scheduler/include/VirtualMachinePoolXML.h +++ b/src/scheduler/include/VirtualMachinePoolXML.h @@ -84,6 +84,15 @@ public: return update(vm->get_oid(), vm->get_template(xml)); }; + /** + * + * + * */ + void clear() + { + flush(); + } + protected: int get_suitable_nodes(vector& content) diff --git a/src/scheduler/src/pool/VMGroupXML.cc b/src/scheduler/src/pool/VMGroupXML.cc index b1cdcec2b5..7a13f684db 100644 --- a/src/scheduler/src/pool/VMGroupXML.cc +++ b/src/scheduler/src/pool/VMGroupXML.cc @@ -18,9 +18,13 @@ void VMGroupXML::init_attributes() { - vector content; + vector content; + std::vector srules; + + std::vector::iterator it; xpath(oid, "/VM_GROUP/ID", -1); + xpath(name,"/VM_GROUP/NAME", "undefined"); // VMGroup roles get_nodes("/VM_GROUP/ROLES", content); @@ -33,5 +37,33 @@ void VMGroupXML::init_attributes() free_nodes(content); content.clear(); + + xpaths(srules, "/VM_GROUP/TEMPLATE/AFFINED"); + + for ( it = srules.begin() ; it != srules.end(); ++it ) + { + std::set id_set; + + roles.names_to_ids(*it, id_set); + + VMGroupRule rule(VMGroupRule::AFFINED, id_set); + + rules.insert(rule); + } + + rules.clear(); + + xpaths(srules, "/VM_GROUP/TEMPLATE/ANTI_AFFINED"); + + for ( it = srules.begin() ; it != srules.end(); ++it ) + { + std::set id_set; + + roles.names_to_ids(*it, id_set); + + VMGroupRule rule(VMGroupRule::ANTI_AFFINED, id_set); + + rules.insert(rule); + } }; diff --git a/src/scheduler/src/sched/Scheduler.cc b/src/scheduler/src/sched/Scheduler.cc index 04d0159aae..ac0f28b91a 100644 --- a/src/scheduler/src/sched/Scheduler.cc +++ b/src/scheduler/src/sched/Scheduler.cc @@ -308,21 +308,23 @@ void Scheduler::start() // ------------------------------------------------------------------------- // Pools // ------------------------------------------------------------------------- + acls = new AclXML(Client::client(), zone_id); + upool = new UserPoolXML(Client::client()); hpool = new HostPoolXML(Client::client()); - upool = new UserPoolXML(Client::client()); clpool = new ClusterPoolXML(Client::client()); - vmpool = new VirtualMachinePoolXML(Client::client(), machines_limit, - live_rescheds==1); - - vmapool = new VirtualMachineActionsPoolXML(Client::client(), machines_limit); dspool = new SystemDatastorePoolXML(Client::client()); img_dspool = new ImageDatastorePoolXML(Client::client()); + vmpool = new VirtualMachinePoolXML(Client::client(), machines_limit, + live_rescheds==1); + vm_roles_pool = new VirtualMachinePoolXML(Client::client(), machines_limit, + live_rescheds==1); + vmgpool = new VMGroupPoolXML(Client::client()); - acls = new AclXML(Client::client(), zone_id); + vmapool = new VirtualMachineActionsPoolXML(Client::client(), machines_limit); // ----------------------------------------------------------- // Load scheduler policies @@ -470,6 +472,8 @@ int Scheduler::set_up_pools() return rc; } + vm_roles_pool->clear(); + return 0; }; diff --git a/src/vm_group/VMGroup.cc b/src/vm_group/VMGroup.cc index 6c7cfa1ee9..68d22e1cd2 100644 --- a/src/vm_group/VMGroup.cc +++ b/src/vm_group/VMGroup.cc @@ -235,25 +235,17 @@ int VMGroup::check_rule_names(VMGroupRule::Policy policy, std::string& error) for ( jt = affined.begin() ; jt != affined.end() ; ++jt ) { - std::set a_set, key_set; - std::set::iterator s_it; - std::set id_set; - one_util::split_unique((*jt)->value(), ',', a_set); - - for (s_it = a_set.begin(); s_it != a_set.end() ; ++s_it) - { - key_set.insert(one_util::trim(*s_it)); - } - - if ( roles.names_to_ids(key_set, id_set) != 0 ) + if ( roles.names_to_ids((*jt)->value(), id_set) != 0 ) { std::ostringstream oss; + oss << "Some roles used in " << aname << " attribute (" << (*jt)->value() << ") are not defined"; error = oss.str(); + return -1; } } @@ -276,21 +268,11 @@ int VMGroup::get_rules(VMGroupRule::Policy policy, VMGroupRule::rule_set& rules, for ( jt = affined.begin() ; jt != affined.end() ; ++jt ) { - std::set a_set, key_set; - std::set::iterator s_it; - std::set id_set; std::pair::iterator, bool> rc; - one_util::split_unique((*jt)->value(), ',', a_set); - - for (s_it = a_set.begin(); s_it != a_set.end() ; ++s_it) - { - key_set.insert(one_util::trim(*s_it)); - } - - roles.names_to_ids(key_set, id_set); + roles.names_to_ids((*jt)->value(), id_set); VMGroupRule rule(policy, id_set); @@ -298,8 +280,12 @@ int VMGroup::get_rules(VMGroupRule::Policy policy, VMGroupRule::rule_set& rules, if ( rc.second == false ) { - error_str = "Duplicated " + aname + " rule (" + - (*jt)->value() + ") detected."; + std::ostringstream oss; + + oss << "Duplicated " << aname << " rule (" << (*jt)->value() + << ") detected."; + + error_str = oss.str(); return -1; } diff --git a/src/vm_group/VMGroupRole.cc b/src/vm_group/VMGroupRole.cc index e24636d0f5..9a3eddd0b0 100644 --- a/src/vm_group/VMGroupRole.cc +++ b/src/vm_group/VMGroupRole.cc @@ -32,6 +32,7 @@ VMGroupRole::VMGroupRole(VectorAttribute *_va):va(_va) } } +/* -------------------------------------------------------------------------- */ /* -------------------------------------------------------------------------- */ void VMGroupRole::add_vm(int vm_id) @@ -76,6 +77,60 @@ void VMGroupRole::set_vms() /* -------------------------------------------------------------------------- */ /* -------------------------------------------------------------------------- */ +static void affinity_requirements(int vm_id, std::string& requirements, + VMGroupRole::Policy policy, const std::set& vms) +{ + string op; + + requirements = ""; + + switch(policy) + { + case VMGroupRole::AFFINED: + op = "="; + break; + case VMGroupRole::ANTI_AFFINED: + op = "!="; + break; + case VMGroupRole::NONE: + return; + } + + std::ostringstream oss; + std::set::const_iterator it; + + for ( it = vms.begin(); it != vms.end(); ++it ) + { + if ( vm_id == -1 || vm_id != *it ) + { + if ( it != vms.begin() ) + { + oss << " & "; + } + + oss << "( CURRENT_VMS " << op << " " << *it << ") "; + } + } + + requirements = oss.str(); +} + +void VMGroupRole::vm_role_requirements(int vm_id, std::string& requirements) +{ + affinity_requirements(vm_id, requirements, policy(), vms); +} + +void VMGroupRole::role_requirements(Policy policy, std::string& requirements) +{ + affinity_requirements(-1, requirements, policy, vms); +} + +/* -------------------------------------------------------------------------- */ +/* -------------------------------------------------------------------------- */ +/* VMGroupRoles */ +/* -------------------------------------------------------------------------- */ +/* -------------------------------------------------------------------------- */ + int VMGroupRoles::from_xml_node(const xmlNodePtr node) { std::vector roles; @@ -125,6 +180,7 @@ int VMGroupRoles::from_xml_node(const xmlNodePtr node) return 0; } +/* -------------------------------------------------------------------------- */ /* -------------------------------------------------------------------------- */ int VMGroupRoles::add_role(VectorAttribute * vrole, string& error) @@ -207,6 +263,9 @@ int VMGroupRoles::del_vm(const std::string& role_name, int vmid) return 0; } +/* -------------------------------------------------------------------------- */ +/* -------------------------------------------------------------------------- */ + int VMGroupRoles::vm_size() { int total = 0; @@ -222,12 +281,19 @@ int VMGroupRoles::vm_size() /* -------------------------------------------------------------------------- */ /* -------------------------------------------------------------------------- */ -int VMGroupRoles::names_to_ids(const std::set keys, - std::set& keyi) +int VMGroupRoles::names_to_ids(const std::string& rnames, std::set& keyi) { + std::set a_set, key_set; std::set::iterator it; - for ( it = keys.begin(); it != keys.end(); ++it ) + one_util::split_unique(rnames, ',', a_set); + + for ( it = a_set.begin(); it != a_set.end() ; ++it ) + { + key_set.insert(one_util::trim(*it)); + } + + for ( it = key_set.begin(); it != key_set.end(); ++it ) { VMGroupRole *r = by_name.get(*it);