diff --git a/include/Nebula.h b/include/Nebula.h index ef6575cff6..41718f0f59 100644 --- a/include/Nebula.h +++ b/include/Nebula.h @@ -407,7 +407,7 @@ private: // Configuration // --------------------------------------------------------------- - NebulaTemplate * nebula_configuration; + OpenNebulaTemplate * nebula_configuration; // --------------------------------------------------------------- // Nebula Pools diff --git a/include/NebulaTemplate.h b/include/NebulaTemplate.h index 06357214df..fe213e89fa 100644 --- a/include/NebulaTemplate.h +++ b/include/NebulaTemplate.h @@ -20,16 +20,25 @@ #include "Template.h" #include +/** + * This class provides the basic abstraction for OpenNebula configuration files + */ class NebulaTemplate : public Template -{ +{ public: + // ----------------------------------------------------------------------- + // ----------------------------------------------------------------------- - NebulaTemplate(string& etc_location, string& var_location); + NebulaTemplate(const string& etc_location, const char * _conf_name) + { + conf_file = etc_location + _conf_name; + } - ~NebulaTemplate(){}; + virtual ~NebulaTemplate(){}; + + // ----------------------------------------------------------------------- + // ----------------------------------------------------------------------- - static const char * conf_name; - int get(const char * name, vector& values) const { string _name(name); @@ -50,41 +59,95 @@ public: Template::get(_name,values); }; + + void get(const char *name, unsigned int& values) const + { + int ival; + + NebulaTemplate::get(name, ival); + + values = static_cast(ival); + }; void get(const char * name, time_t& values) const { - const SingleAttribute * sattr; - vector attr; + const SingleAttribute * sattr; + vector attr; - string _name(name); + string _name(name); if ( Template::get(_name,attr) == 0 ) { - values = 0; - return; + values = 0; + return; } sattr = dynamic_cast(attr[0]); if ( sattr != 0 ) { - istringstream is; - - is.str(sattr->value()); - is >> values; + istringstream is; + + is.str(sattr->value()); + is >> values; } else - values = 0; + values = 0; }; -private: - friend class Nebula; - + // ----------------------------------------------------------------------- + // ----------------------------------------------------------------------- + + /** + * Parse and loads the configuration in the template + */ + int load_configuration(); + +protected: + /** + * Full path to the configuration file + */ string conf_file; + /** + * Defaults for the configuration file + */ map conf_default; + + /** + * Sets the defaults value for the template + */ + virtual void set_conf_default() = 0; +}; + +// ----------------------------------------------------------------------------- +// ----------------------------------------------------------------------------- + +class OpenNebulaTemplate : public NebulaTemplate +{ +public: + + OpenNebulaTemplate(const string& etc_location, const string& _var_location): + NebulaTemplate(etc_location, conf_name), var_location(_var_location) + {}; - int load_configuration(); + ~OpenNebulaTemplate(){}; + +private: + /** + * Name for the configuration file, oned.conf + */ + static const char * conf_name; + + /** + * Path for the var directory, for defaults + */ + string var_location; + + /** + * Sets the defaults value for the template + */ + void set_conf_default(); }; diff --git a/install.sh b/install.sh index cf822b82a8..1abc401669 100755 --- a/install.sh +++ b/install.sh @@ -761,6 +761,7 @@ ONEDB_MIGRATOR_FILES="src/onedb/2.0_to_2.9.80.rb \ ETC_FILES="share/etc/oned.conf \ share/etc/defaultrc \ + src/scheduler/etc/sched.conf \ src/cli/etc/group.default" VMWARE_ETC_FILES="src/vmm_mad/remotes/vmware/vmwarerc" diff --git a/share/scripts/one b/share/scripts/one index b54de174b8..c72e1f5826 100755 --- a/share/scripts/one +++ b/share/scripts/one @@ -43,18 +43,10 @@ fi KILL_9_SECONDS=5 #------------------------------------------------------------------------------ -# Function that checks for running daemons and gets PORT from conf +# Function that checks for running daemons #------------------------------------------------------------------------------ setup() { - PORT=$(sed -n '/^[ \t]*PORT/s/^.*PORT\s*=\s*\([0-9]\+\)\s*.*$/\1/p' \ - $ONE_CONF) - - if [ $? -ne 0 ]; then - echo "Can not find PORT in $ONE_CONF." - exit 1 - fi - if [ -f $LOCK_FILE ]; then if [ -f $ONE_PID ]; then ONEPID=`cat $ONE_PID` @@ -150,17 +142,7 @@ start() fi # Start the scheduler - # The following command line arguments are supported by mm_shed: - # [-p port] to connect to oned - default: 2633 - # [-t timer] seconds between two scheduling actions - default: 30 - # [-m machines limit] max number of VMs managed in each scheduling action - # - default: 300 - # [-d dispatch limit] max number of VMs dispatched in each scheduling action - # - default: 30 - # [-h host dispatch] max number of VMs dispatched to a given host in each - # scheduling action - default: 1 - - $ONE_SCHEDULER -p $PORT -t 30 -m 300 -d 30 -h 1& + $ONE_SCHEDULER& LASTRC=$? LASTPID=$! diff --git a/src/nebula/Nebula.cc b/src/nebula/Nebula.cc index b5267e9265..61d0b0870d 100644 --- a/src/nebula/Nebula.cc +++ b/src/nebula/Nebula.cc @@ -56,7 +56,7 @@ void Nebula::start() // Configuration // ----------------------------------------------------------- - nebula_configuration = new NebulaTemplate(etc_location, var_location); + nebula_configuration = new OpenNebulaTemplate(etc_location, var_location); rc = nebula_configuration->load_configuration(); diff --git a/src/nebula/NebulaTemplate.cc b/src/nebula/NebulaTemplate.cc index 1d7b6272cd..e0d2c590c8 100644 --- a/src/nebula/NebulaTemplate.cc +++ b/src/nebula/NebulaTemplate.cc @@ -15,33 +15,75 @@ /* -------------------------------------------------------------------------- */ #include "NebulaTemplate.h" -#include "Nebula.h" using namespace std; /* -------------------------------------------------------------------------- */ /* -------------------------------------------------------------------------- */ -const char * NebulaTemplate::conf_name="oned.conf"; - -/* -------------------------------------------------------------------------- */ -/* -------------------------------------------------------------------------- */ - -NebulaTemplate::NebulaTemplate(string& etc_location, string& var_location) +int NebulaTemplate::load_configuration() +{ + char * error = 0; + int rc; + + string aname; + Attribute * attr; + + map::iterator iter, j; + + set_conf_default(); + + rc = parse(conf_file.c_str(), &error); + + if ( rc != 0 && error != 0) + { + cout << "\nError while parsing configuration file:\n" << error << endl; + + free(error); + + return -1; + } + + for(iter=conf_default.begin();iter!=conf_default.end();) + { + aname = iter->first; + attr = iter->second; + + j = attributes.find(aname); + + if ( j == attributes.end() ) + { + attributes.insert(make_pair(aname,attr)); + iter++; + } + else + { + delete iter->second; + conf_default.erase(iter++); + } + } + + return 0; +} +/* -------------------------------------------------------------------------- */ +/* -------------------------------------------------------------------------- */ + +const char * OpenNebulaTemplate::conf_name="oned.conf"; + +/* -------------------------------------------------------------------------- */ +/* -------------------------------------------------------------------------- */ + +void OpenNebulaTemplate::set_conf_default() { - ostringstream os; SingleAttribute * attribute; VectorAttribute * vattribute; string value; - conf_file = etc_location + conf_name; - // MANAGER_TIMER value = "15"; attribute = new SingleAttribute("MANAGER_TIMER",value); conf_default.insert(make_pair(attribute->name(),attribute)); - /* #******************************************************************************* # Daemon configuration attributes @@ -170,49 +212,3 @@ NebulaTemplate::NebulaTemplate(string& etc_location, string& var_location) conf_default.insert(make_pair(attribute->name(),attribute)); } -/* -------------------------------------------------------------------------- */ -/* -------------------------------------------------------------------------- */ - - -int NebulaTemplate::load_configuration() -{ - char * error = 0; - map::iterator iter, j; - int rc; - - string aname; - Attribute * attr; - - rc = parse(conf_file.c_str(), &error); - - if ( rc != 0 && error != 0) - { - - cout << "\nError while parsing configuration file:\n" << error << endl; - - free(error); - - return -1; - } - - for(iter=conf_default.begin();iter!=conf_default.end();) - { - aname = iter->first; - attr = iter->second; - - j = attributes.find(aname); - - if ( j == attributes.end() ) - { - attributes.insert(make_pair(aname,attr)); - iter++; - } - else - { - delete iter->second; - conf_default.erase(iter++); - } - } - - return 0; -} diff --git a/src/scheduler/etc/sched.conf b/src/scheduler/etc/sched.conf new file mode 100644 index 0000000000..b72f48dd37 --- /dev/null +++ b/src/scheduler/etc/sched.conf @@ -0,0 +1,51 @@ +#******************************************************************************* +# OpenNebula Configuration file +#******************************************************************************* + +#******************************************************************************* +# Daemon configuration attributes +#------------------------------------------------------------------------------- +# ONED_PORT: Port to connect to the OpenNebula daemon (oned) +# +# SCHED_INTERVAL: Seconds between two scheduling actions +# +# MAX_VM: Maximum number of Virtual Machines scheduled in each scheduling +# action +# +# MAX_DISPATCH: Maximum number of Virtual Machines actually dispatched to a +# host in each scheduling action +# +# MAX_HOST: Maximum number of Virtual Machines dispatched to a given host in +# each scheduling action +# +# DEFAULT_SCHED: Definition of the default scheduling algorithm +# - policy: +# 0 = Packing. Heuristic that minimizes the number of hosts in use by +# packing the VMs in the hosts to reduce VM fragmentation +# 1 = Striping. Heuristic that tries to maximize resources available for +# the VMs by spreading the VMs in the hosts +# 2 = Load-aware. Heuristic that tries to maximize resources available for +# the VMs by usingthose nodes with less load +# 3 = Custom. +# - rank: Custom arithmetic exprission to rank suitable hosts based in their +# attributes +#******************************************************************************* + +ONED_PORT = 2633 + +SCHED_INTERVAL = 30 + +MAX_VM = 300 + +MAX_DISPATCH = 30 + +MAX_HOST = 1 + +DEFAULT_SCHED = [ + policy = 1 +] + +#DEFAULT_SCHED = [ +# policy = 3, +# rank = "- (RUNNING_VMS * 50 + FREE_CPU)" +#] diff --git a/src/scheduler/include/RankPolicy.h b/src/scheduler/include/RankPolicy.h index 628a51c717..b6c337bf1e 100644 --- a/src/scheduler/include/RankPolicy.h +++ b/src/scheduler/include/RankPolicy.h @@ -29,12 +29,16 @@ public: RankPolicy( VirtualMachinePoolXML * vmpool, HostPoolXML * hpool, - float w=1.0):SchedulerHostPolicy(vmpool,hpool,w){}; + const string& dr, + float w = 1.0) + :SchedulerHostPolicy(vmpool,hpool,w), default_rank(dr){}; ~RankPolicy(){}; private: + string default_rank; + void policy( VirtualMachineXML * vm) { @@ -53,10 +57,10 @@ private: srank = vm->get_rank(); - if (srank == "") + if (srank.empty()) { - NebulaLog::log("RANK",Log::WARNING,"No rank defined for VM"); - } + srank = default_rank; + } for (i=0;i #include "Scheduler.h" +#include "SchedulerTemplate.h" #include "RankPolicy.h" #include "NebulaLog.h" @@ -64,33 +65,44 @@ extern "C" void * scheduler_action_loop(void *arg) void Scheduler::start() { int rc; - ifstream file; + + ifstream file; + ostringstream oss; + + string etc_path; + int oned_port; pthread_attr_t pattr; // ----------------------------------------------------------- - // Log system + // Log system & Configuration File // ----------------------------------------------------------- try { - ostringstream oss; + string log_file; const char * nl = getenv("ONE_LOCATION"); if (nl == 0) //OpenNebula installed under root directory { - oss << "/var/log/one/"; + log_file = "/var/log/one/sched.log"; + etc_path = "/etc/one/"; } else { - oss << nl << "/var/"; - } + oss << nl << "/var/sched.log"; - oss << "sched.log"; + log_file = oss.str(); + + oss.str(""); + oss << nl << "/etc/"; + + etc_path = oss.str(); + } NebulaLog::init_log_system(NebulaLog::FILE, Log::DEBUG, - oss.str().c_str()); + log_file.c_str()); NebulaLog::log("SCHED", Log::INFO, "Init Scheduler Log system"); } @@ -99,6 +111,42 @@ void Scheduler::start() throw; } + // ----------------------------------------------------------- + // Configuration File + // ----------------------------------------------------------- + + SchedulerTemplate conf(etc_path); + + if ( conf.load_configuration() != 0 ) + { + throw runtime_error("Error reading configuration file."); + } + + conf.get("ONED_PORT", oned_port); + + oss.str(""); + oss << "http://localhost:" << oned_port << "/RPC2"; + url = oss.str(); + + conf.get("SCHED_INTERVAL", timer); + + conf.get("MAX_VM", machines_limit); + + conf.get("MAX_DISPATCH", dispatch_limit); + + conf.get("MAX_HOST", host_dispatch_limit); + + oss.str(""); + + oss << "Starting Scheduler Daemon" << endl; + oss << "----------------------------------------\n"; + oss << " Scheduler Configuration File \n"; + oss << "----------------------------------------\n"; + oss << conf; + oss << "----------------------------------------"; + + NebulaLog::log("SCHED", Log::INFO, oss); + // ----------------------------------------------------------- // XML-RPC Client // ----------------------------------------------------------- @@ -128,7 +176,7 @@ void Scheduler::start() // Load scheduler policies // ----------------------------------------------------------- - register_policies(); + register_policies(conf); // ----------------------------------------------------------- // Close stds, we no longer need them diff --git a/src/scheduler/src/sched/SchedulerTemplate.cc b/src/scheduler/src/sched/SchedulerTemplate.cc new file mode 100644 index 0000000000..43ffbd897f --- /dev/null +++ b/src/scheduler/src/sched/SchedulerTemplate.cc @@ -0,0 +1,126 @@ +/* -------------------------------------------------------------------------- */ +/* Copyright 2002-2011, OpenNebula Project Leads (OpenNebula.org) */ +/* */ +/* Licensed under the Apache License, Version 2.0 (the "License"); you may */ +/* not use this file except in compliance with the License. You may obtain */ +/* a copy of the License at */ +/* */ +/* http://www.apache.org/licenses/LICENSE-2.0 */ +/* */ +/* Unless required by applicable law or agreed to in writing, software */ +/* distributed under the License is distributed on an "AS IS" BASIS, */ +/* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. */ +/* See the License for the specific language governing permissions and */ +/* limitations under the License. */ +/* -------------------------------------------------------------------------- */ + +#include "SchedulerTemplate.h" + +/* -------------------------------------------------------------------------- */ +/* -------------------------------------------------------------------------- */ + +const char * SchedulerTemplate::conf_name="sched.conf"; + +/* -------------------------------------------------------------------------- */ +/* -------------------------------------------------------------------------- */ + +void SchedulerTemplate::set_conf_default() +{ + SingleAttribute * attribute; + VectorAttribute * vattribute; + string value; + +/* +#******************************************************************************* +# Daemon configuration attributes +#------------------------------------------------------------------------------- +# ONED_PORT +# SCHED_INTERVAL +# MAX_VM +# MAX_DISPATCH +# MAX_HOST +# DEFAULT_SCHED +#------------------------------------------------------------------------------- +*/ + // ONED_PORT + value = "2633"; + + attribute = new SingleAttribute("ONED_PORT",value); + conf_default.insert(make_pair(attribute->name(),attribute)); + + // SCHED_INTERVAL + value = "30"; + + attribute = new SingleAttribute("SCHED_INTERVAL",value); + conf_default.insert(make_pair(attribute->name(),attribute)); + + // MAX_VM + value = "300"; + + attribute = new SingleAttribute("MAX_VM",value); + conf_default.insert(make_pair(attribute->name(),attribute)); + + // MAX_DISPATCH + value = "30"; + + attribute = new SingleAttribute("MAX_DISPATCH",value); + conf_default.insert(make_pair(attribute->name(),attribute)); + + //MAX_HOST + value = "1"; + + attribute = new SingleAttribute("MAX_HOST",value); + conf_default.insert(make_pair(attribute->name(),attribute)); + + //DEFAULT_SCHED + map vvalue; + vvalue.insert(make_pair("POLICY","1")); + + vattribute = new VectorAttribute("DEFAULT_SCHED",vvalue); + conf_default.insert(make_pair(attribute->name(),vattribute)); +} + +/* -------------------------------------------------------------------------- */ +/* -------------------------------------------------------------------------- */ + +string SchedulerTemplate::get_policy() const +{ + int policy; + string rank; + + istringstream iss; + + vector vsched; + const VectorAttribute * sched; + + get("DEFAULT_SCHED", vsched); + + sched = static_cast (vsched[0]); + + iss.str(sched->vector_value("POLICY")); + iss >> policy; + + switch (policy) + { + case 0: //Packing + rank = "RUNNING_VMS"; + break; + + case 1: //Striping + rank = "- RUNNING_VMS"; + break; + + case 2: //Load-aware + rank = "FREE_CPU"; + break; + + case 3: //Custom + rank = sched->vector_value("RANK"); + break; + + default: + rank = ""; + } + + return rank; +} \ No newline at end of file diff --git a/src/scheduler/src/sched/mm_sched.cc b/src/scheduler/src/sched/mm_sched.cc index 01e667f1b3..9e5104e6c1 100644 --- a/src/scheduler/src/sched/mm_sched.cc +++ b/src/scheduler/src/sched/mm_sched.cc @@ -15,6 +15,7 @@ /* -------------------------------------------------------------------------- */ #include "Scheduler.h" +#include "SchedulerTemplate.h" #include "RankPolicy.h" #include #include @@ -31,16 +32,7 @@ class RankScheduler : public Scheduler { public: - RankScheduler(string url, - time_t timer, - unsigned int machines_limit, - unsigned int dispatch_limit, - unsigned int host_dispatch_limit - ):Scheduler(url, - timer, - machines_limit, - dispatch_limit, - host_dispatch_limit),rp(0){}; + RankScheduler():Scheduler(),rp(0){}; ~RankScheduler() { @@ -50,9 +42,9 @@ public: } }; - void register_policies() + void register_policies(const SchedulerTemplate& conf) { - rp = new RankPolicy(vmpool,hpool,1.0); + rp = new RankPolicy(vmpool, hpool, conf.get_policy(), 1.0); add_host_policy(rp); }; @@ -64,56 +56,11 @@ private: int main(int argc, char **argv) { - RankScheduler * ss; - int port = 2633; - time_t timer= 30; - unsigned int machines_limit = 300; - unsigned int dispatch_limit = 30; - unsigned int host_dispatch_limit = 1; - char opt; - - ostringstream oss; - - while((opt = getopt(argc,argv,"p:t:m:d:h:")) != -1) - { - switch(opt) - { - case 'p': - port = atoi(optarg); - break; - case 't': - timer = atoi(optarg); - break; - case 'm': - machines_limit = atoi(optarg); - break; - case 'd': - dispatch_limit = atoi(optarg); - break; - case 'h': - host_dispatch_limit = atoi(optarg); - break; - default: - cerr << "usage: " << argv[0] << " [-p port] [-t timer] "; - cerr << "[-m machines limit] [-d dispatch limit] [-h host_dispatch_limit]\n"; - exit(-1); - break; - } - }; - - /* ---------------------------------------------------------------------- */ - - oss << "http://localhost:" << port << "/RPC2"; - - ss = new RankScheduler(oss.str(), - timer, - machines_limit, - dispatch_limit, - host_dispatch_limit); + RankScheduler ss; try { - ss->start(); + ss.start(); } catch (exception &e) { @@ -122,7 +69,5 @@ int main(int argc, char **argv) return -1; } - delete ss; - return 0; } diff --git a/src/vm/VirtualMachineTemplate.cc b/src/vm/VirtualMachineTemplate.cc index 44fb3ed5a3..5fc83995b9 100644 --- a/src/vm/VirtualMachineTemplate.cc +++ b/src/vm/VirtualMachineTemplate.cc @@ -24,7 +24,8 @@ const string VirtualMachineTemplate::RESTRICTED_ATTRIBUTES[] = { "CONTEXT/FILES", "DISK/SOURCE", "NIC/MAC", - "NIC/VLAN_ID" + "NIC/VLAN_ID", + "RANK" }; const int VirtualMachineTemplate::RS_ATTRS_LENGTH = 3;