From 8ff221052d80f191eb7eabc7ddc8a6d994dfd54a Mon Sep 17 00:00:00 2001 From: "Ruben S. Montero" Date: Thu, 26 Apr 2012 19:06:49 +0200 Subject: [PATCH 1/5] feature #1243: Add resched flag to VMs. Includes associated logic to make it work: RM methods, OCA bindings, CLI commands. LCM updated to clear the resched flag when leaving the running state Fixes VM tests --- SConstruct | 30 ++++----- include/DispatchManager.h | 11 ++++ include/VirtualMachine.h | 21 +++++++ src/cli/one_helper/onevm_helper.rb | 7 ++- src/cli/onevm | 24 ++++++++ src/dm/DispatchManagerActions.cc | 46 ++++++++++++++ src/lcm/LifeCycleActions.cc | 19 +++++- src/lcm/LifeCycleStates.cc | 6 ++ .../opennebula/client/vm/VirtualMachine.java | 18 ++++++ src/oca/ruby/OpenNebula/VirtualMachine.rb | 10 +++ src/ozones/test/test.sh | 8 +-- src/rm/RequestManagerVirtualMachine.cc | 8 +++ src/test/Nebula.cc | 7 ++- src/vm/VirtualMachine.cc | 3 + src/vm/test/SConstruct | 13 +++- src/vm/test/VirtualMachinePoolTest.cc | 61 +++++++++++++++---- 16 files changed, 255 insertions(+), 37 deletions(-) diff --git a/SConstruct b/SConstruct index cf962f4d85..c5db663582 100644 --- a/SConstruct +++ b/SConstruct @@ -237,22 +237,22 @@ if testing=='yes': ]) build_scripts.extend([ - 'src/authm/test/SConstruct', - 'src/common/test/SConstruct', - 'src/host/test/SConstruct', - 'src/cluster/test/SConstruct', - 'src/datastore/test/SConstruct', - 'src/group/test/SConstruct', - 'src/image/test/SConstruct', - 'src/lcm/test/SConstruct', - 'src/pool/test/SConstruct', - 'src/template/test/SConstruct', - 'src/test/SConstruct', - 'src/um/test/SConstruct', +# 'src/authm/test/SConstruct', +# 'src/common/test/SConstruct', +# 'src/host/test/SConstruct', +# 'src/cluster/test/SConstruct', +# 'src/datastore/test/SConstruct', +# 'src/group/test/SConstruct', +# 'src/image/test/SConstruct', +# 'src/lcm/test/SConstruct', +# 'src/pool/test/SConstruct', +# 'src/template/test/SConstruct', +# 'src/test/SConstruct', +# 'src/um/test/SConstruct', 'src/vm/test/SConstruct', - 'src/vnm/test/SConstruct', - 'src/xml/test/SConstruct', - 'src/vm_template/test/SConstruct', +# 'src/vnm/test/SConstruct', +# 'src/xml/test/SConstruct', +# 'src/vm_template/test/SConstruct', ]) else: main_env.Append(testing='no') diff --git a/include/DispatchManager.h b/include/DispatchManager.h index 1bf3e4cf22..2ad6b03649 100644 --- a/include/DispatchManager.h +++ b/include/DispatchManager.h @@ -219,6 +219,17 @@ public: int reboot( int vid); + /** + * Set the re-scheduling flag for the VM (must be in RUNNING state) + * @param vid VirtualMachine identification + * @param do_resched set or unset the flag + * @return 0 on success, -1 if the VM does not exits or -2 if the VM is + * in a wrong a state + */ + int resched( + int vid, + bool do_resched); + private: /** * Thread id for the Dispatch Manager diff --git a/include/VirtualMachine.h b/include/VirtualMachine.h index 9254ec2b4c..be2ba87c0f 100644 --- a/include/VirtualMachine.h +++ b/include/VirtualMachine.h @@ -586,6 +586,22 @@ public: lcm_state = s; }; + /** + * Sets the re-scheduling flag + * @param set or unset the re-schedule flag + */ + void set_resched(bool do_sched) + { + if ( do_sched == true ) + { + resched = 1; + } + else + { + resched = 0; + } + }; + // ------------------------------------------------------------------------ // Timers // ------------------------------------------------------------------------ @@ -720,6 +736,11 @@ private: */ LcmState lcm_state; + /** + * Marks the VM as to be re-scheduled + */ + int resched; + /** * Start time, the VM enter the nebula system (in epoch) */ diff --git a/src/cli/one_helper/onevm_helper.rb b/src/cli/one_helper/onevm_helper.rb index b772ce61bb..b7d32be70d 100644 --- a/src/cli/one_helper/onevm_helper.rb +++ b/src/cli/one_helper/onevm_helper.rb @@ -57,7 +57,11 @@ class OneVMHelper < OpenNebulaHelper::OneHelper column :NAME, "Name of the Virtual Machine", :left, :size=>15 do |d| - d["NAME"] + if d["RESCHED"] == "1" + "*#{d["NAME"]}" + else + d["NAME"] + end end column :USER, "Username of the Virtual Machine owner", :left, @@ -132,6 +136,7 @@ class OneVMHelper < OpenNebulaHelper::OneHelper puts str % ["GROUP", vm['GNAME']] puts str % ["STATE", vm.state_str] puts str % ["LCM_STATE", vm.lcm_state_str] + puts str % ["RESCHED", OpenNebulaHelper.boolean_to_str(vm['RESCHED'])] puts str % ["HOSTNAME", vm['/VM/HISTORY_RECORDS/HISTORY[last()]/HOSTNAME']] if %w{ACTIVE SUSPENDED}.include? vm.state_str diff --git a/src/cli/onevm b/src/cli/onevm index e8dd16b71f..ddf1d7d52f 100755 --- a/src/cli/onevm +++ b/src/cli/onevm @@ -354,6 +354,30 @@ cmd=CommandParser::CmdParser.new(ARGV) do end end + resched_desc = <<-EOT.unindent + Sets the rescheduling flag for the VM. + + States: RUNNING + EOT + + command :resched, resched_desc, [:range,:vmid_list] do + helper.perform_actions(args[0],options,"Setting resched flag") do |vm| + vm.resched + end + end + + unresched_desc = <<-EOT.unindent + Clears the rescheduling flag for the VM. + + States: RUNNING + EOT + + command :unresched, unresched_desc, [:range,:vmid_list] do + helper.perform_actions(args[0],options,"Clearing resched flag") do |vm| + vm.unresched + end + end + list_desc = <<-EOT.unindent Lists VMs in the pool EOT diff --git a/src/dm/DispatchManagerActions.cc b/src/dm/DispatchManagerActions.cc index 4907ed7194..f573c3218d 100644 --- a/src/dm/DispatchManagerActions.cc +++ b/src/dm/DispatchManagerActions.cc @@ -580,6 +580,52 @@ error: return -2; } + +/* -------------------------------------------------------------------------- */ +/* -------------------------------------------------------------------------- */ + +int DispatchManager::resched(int vid, bool do_resched) +{ + VirtualMachine * vm; + ostringstream oss; + + vm = vmpool->get(vid,true); + + if ( vm == 0 ) + { + return -1; + } + + oss << "Setting rescheduling flag on 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(); + + vm->set_resched(do_resched); + vmpool->update(vm); + } + else + { + goto error; + } + + vm->unlock(); + + return 0; + +error: + oss.str(""); + oss << "Could not set rescheduling flag for VM " << vid << ", wrong state."; + NebulaLog::log("DiM",Log::ERROR,oss); + + vm->unlock(); + + return -2; +} /* -------------------------------------------------------------------------- */ /* -------------------------------------------------------------------------- */ diff --git a/src/lcm/LifeCycleActions.cc b/src/lcm/LifeCycleActions.cc index 6b316d5f14..234e686a58 100644 --- a/src/lcm/LifeCycleActions.cc +++ b/src/lcm/LifeCycleActions.cc @@ -111,6 +111,8 @@ void LifeCycleManager::suspend_action(int vid) vm->set_state(VirtualMachine::SAVE_SUSPEND); + vm->set_resched(false); + vmpool->update(vm); vm->log("LCM", Log::INFO, "New VM state is SAVE_SUSPEND"); @@ -154,7 +156,9 @@ void LifeCycleManager::stop_action(int vid) //---------------------------------------------------- vm->set_state(VirtualMachine::SAVE_STOP); - + + vm->set_resched(false); + vmpool->update(vm); vm->log("LCM", Log::INFO, "New VM state is SAVE_STOP"); @@ -200,6 +204,8 @@ void LifeCycleManager::migrate_action(int vid) vm->set_state(VirtualMachine::SAVE_MIGRATE); + vm->set_resched(false); + vmpool->update(vm); vm->set_stime(time(0)); @@ -254,6 +260,8 @@ void LifeCycleManager::live_migrate_action(int vid) vm->set_state(VirtualMachine::MIGRATE); + vm->set_resched(false); + vmpool->update(vm); vm->set_stime(time(0)); @@ -306,6 +314,8 @@ void LifeCycleManager::shutdown_action(int vid) vm->set_state(VirtualMachine::SHUTDOWN); + vm->set_resched(false); + vmpool->update(vm); vm->log("LCM",Log::INFO,"New VM state is SHUTDOWN"); @@ -410,6 +420,8 @@ void LifeCycleManager::cancel_action(int vid) vm->set_state(VirtualMachine::CANCEL); + vm->set_resched(false); + vmpool->update(vm); vm->log("LCM", Log::INFO, "New state is CANCEL"); @@ -448,6 +460,10 @@ void LifeCycleManager::reboot_action(int vid) VirtualMachineManager * vmm = nd.get_vmm(); vmm->trigger(VirtualMachineManager::REBOOT,vid); + + vm->set_resched(false); //Rebooting cancel re-scheduling actions + + vmpool->update(vm); } else { @@ -595,6 +611,7 @@ void LifeCycleManager::clean_up_vm(VirtualMachine * vm) int vid = vm->get_oid(); vm->set_state(VirtualMachine::CLEANUP); + vm->set_resched(false); vmpool->update(vm); vm->set_etime(the_time); diff --git a/src/lcm/LifeCycleStates.cc b/src/lcm/LifeCycleStates.cc index 391238680b..11cf2bd7be 100644 --- a/src/lcm/LifeCycleStates.cc +++ b/src/lcm/LifeCycleStates.cc @@ -719,6 +719,8 @@ void LifeCycleManager::monitor_suspend_action(int vid) vm->set_state(VirtualMachine::SAVE_SUSPEND); + vm->set_resched(false); + vmpool->update(vm); vm->set_running_etime(the_time); @@ -762,6 +764,8 @@ void LifeCycleManager::monitor_done_action(int vid) vm->set_state(VirtualMachine::UNKNOWN); + vm->set_resched(false); + vmpool->update(vm); vm->log("LCM", Log::INFO, "New VM state is UNKNOWN"); @@ -789,6 +793,8 @@ void LifeCycleManager::failure_action(VirtualMachine * vm) vm->set_state(VirtualMachine::FAILURE); + vm->set_resched(false); + vmpool->update(vm); vm->set_etime(the_time); diff --git a/src/oca/java/src/org/opennebula/client/vm/VirtualMachine.java b/src/oca/java/src/org/opennebula/client/vm/VirtualMachine.java index 9cefefe188..ef10adbdb8 100644 --- a/src/oca/java/src/org/opennebula/client/vm/VirtualMachine.java +++ b/src/oca/java/src/org/opennebula/client/vm/VirtualMachine.java @@ -501,6 +501,24 @@ public class VirtualMachine extends PoolElement{ return action("resubmit"); } + /** + * Sets the re-scheduling flag for the VM + * @return If an error occurs the error message contains the reason. + */ + public OneResponse resched() + { + return action("resched"); + } + + /** + * Unsets the re-scheduling flag for the VM + * @return If an error occurs the error message contains the reason. + */ + public OneResponse unresched() + { + return action("unresched"); + } + /** * Migrates the virtual machine to the target host (hid). *
diff --git a/src/oca/ruby/OpenNebula/VirtualMachine.rb b/src/oca/ruby/OpenNebula/VirtualMachine.rb index a22726f330..d99f30712b 100644 --- a/src/oca/ruby/OpenNebula/VirtualMachine.rb +++ b/src/oca/ruby/OpenNebula/VirtualMachine.rb @@ -194,6 +194,16 @@ module OpenNebula action('resubmit') end + # Sets the re-scheduling flag for the VM + def resched + action('resched') + end + + # Unsets the re-scheduling flag for the VM + def unresched + action('unresched') + end + # Saves a running VM and starts it again in the specified host def migrate(host_id) return Error.new('ID not defined') if !@pe_id diff --git a/src/ozones/test/test.sh b/src/ozones/test/test.sh index d6de0d2f42..76dad892a2 100755 --- a/src/ozones/test/test.sh +++ b/src/ozones/test/test.sh @@ -38,9 +38,9 @@ for j in `ls ./spec/*_spec.rb` ; do ONE_LOCATION=$ONE_LOCATION_A rspec $j -f s CODE=$? - if [ $CODE != 0 ] ; then - break - fi +# if [ $CODE != 0 ] ; then +# break +# fi ONE_LOCATION=$ONE_LOCATION_A oneA/bin/one stop ONE_LOCATION=$ONE_LOCATION_B oneB/bin/one stop @@ -54,4 +54,4 @@ if (($CODE == 0)); then # Delete directories rm -rf oneA rm -rf oneB -fi \ No newline at end of file +fi diff --git a/src/rm/RequestManagerVirtualMachine.cc b/src/rm/RequestManagerVirtualMachine.cc index 1f3973c669..cc8d129704 100644 --- a/src/rm/RequestManagerVirtualMachine.cc +++ b/src/rm/RequestManagerVirtualMachine.cc @@ -233,6 +233,14 @@ void VirtualMachineAction::request_execute(xmlrpc_c::paramList const& paramList, { rc = dm->reboot(id); } + else if (action == "resched") + { + rc = dm->resched(id, true); + } + else if (action == "unresched") + { + rc = dm->resched(id, false); + } switch (rc) { diff --git a/src/test/Nebula.cc b/src/test/Nebula.cc index bd9a202997..6a867ee17c 100644 --- a/src/test/Nebula.cc +++ b/src/test/Nebula.cc @@ -166,11 +166,12 @@ void Nebula::start() hook_location = nebula_location + "hooks/"; remotes_location = nebula_location + "var/remotes/"; - if ( nebula_configuration != 0) + /*if ( nebula_configuration != 0) { delete nebula_configuration; - } - + }*/ + nebula_configuration = new OpenNebulaTemplate(etc_location, var_location); + xmlInitParser(); // ----------------------------------------------------------- diff --git a/src/vm/VirtualMachine.cc b/src/vm/VirtualMachine.cc index d2bae041c9..6810f01bcb 100644 --- a/src/vm/VirtualMachine.cc +++ b/src/vm/VirtualMachine.cc @@ -47,6 +47,7 @@ VirtualMachine::VirtualMachine(int id, last_poll(0), state(INIT), lcm_state(LCM_INIT), + resched(0), stime(time(0)), etime(0), deploy_id(""), @@ -1386,6 +1387,7 @@ string& VirtualMachine::to_xml_extended(string& xml, bool extended) const << "" << last_poll << "" << "" << state << "" << "" << lcm_state << "" + << "" << resched << "" << "" << stime << "" << "" << etime << "" << "" << deploy_id << "" @@ -1452,6 +1454,7 @@ int VirtualMachine::from_xml(const string &xml_str) rc += xpath(last_poll, "/VM/LAST_POLL", 0); rc += xpath(istate, "/VM/STATE", 0); rc += xpath(ilcmstate, "/VM/LCM_STATE", 0); + rc += xpath(resched, "/VM/RESCHED", 0); rc += xpath(stime, "/VM/STIME", 0); rc += xpath(etime, "/VM/ETIME", 0); diff --git a/src/vm/test/SConstruct b/src/vm/test/SConstruct index 98fd9ad244..06f2085cbb 100644 --- a/src/vm/test/SConstruct +++ b/src/vm/test/SConstruct @@ -17,6 +17,13 @@ Import('env') env.Prepend(LIBS=[ + 'nebula_core_test', + 'nebula_lcm', + 'nebula_tm', + 'nebula_vmm', + 'nebula_im', + 'nebula_rm', + 'nebula_dm', 'nebula_um', 'nebula_vm', 'nebula_hm', @@ -26,6 +33,8 @@ env.Prepend(LIBS=[ 'nebula_group', 'nebula_template', 'nebula_pool', + 'nebula_host', + 'nebula_vmtemplate', 'nebula_xml', 'nebula_image', 'nebula_datastore', @@ -39,4 +48,6 @@ env.Prepend(LIBS=[ 'crypto' ]) -env.Program('test','VirtualMachinePoolTest.cc') +nt = env.Object('NebulaTemplateTest.o', '../../nebula/NebulaTemplate.cc') + +env.Program('test',[nt,'VirtualMachinePoolTest.cc']) diff --git a/src/vm/test/VirtualMachinePoolTest.cc b/src/vm/test/VirtualMachinePoolTest.cc index 3a0ac90c90..8f5f7a9ac7 100644 --- a/src/vm/test/VirtualMachinePoolTest.cc +++ b/src/vm/test/VirtualMachinePoolTest.cc @@ -46,12 +46,12 @@ const string templates[] = const string xmls[] = { - "01231the_userusersVM one110000000010000000000000000", + "01231the_userusersVM one1100000000100000000000000000", - "12611the_userusersSecond VM110000000010000000000000000", + "12611the_userusersSecond VM1100000000100000000000000000", "01231the_userusersVM one01000000000000100000000000000000" @@ -60,16 +60,28 @@ const string xmls[] = // This xml dump result has the STIMEs modified to 0000000000 const string xml_dump = - "011the_userusersVM one110000000010000000000000000121the_userusersSecond VM110000000020000000000000000"; + "011the_userusersVM one1100000000100000000000000000121the_userusersSecond VM1100000000200000000000000000"; const string xml_dump_where = - "011the_userusersVM one110000000010000000000000000"; + "011the_userusersVM one1100000000100000000000000000"; const string xml_history_dump = - "001the_userusersVM one110000000010000000000000000101the_userusersSecond VM1100000000200000000000000000A_hostnameA_vm_dir000A_vmm_madA_vnm_mad0000000201the_userusersVM one1100000000200000000000000001C_hostnameC_vm_dir200C_vmm_madC_vnm_mad0000000311the_userusersVM one110000000060000000000000000"; + "001the_userusersVM one1100000000100000000000000000101the_userusersSecond VM11000000002000000000000000000A_hostname000A_vmm_madA_vnm_mad0000000201the_userusersVM one11000000002000000000000000001C_hostname200C_vmm_madC_vnm_mad0000000311the_userusersVM one1100000000600000000000000000"; /* ************************************************************************* */ /* ************************************************************************* */ +#include "NebulaTest.h" + +class NebulaTestVM: public NebulaTest +{ +public: + NebulaTestVM():NebulaTest() + { + NebulaTest::the_tester = this; + + need_vm_pool = true; + } +}; class VirtualMachinePoolFriend : public VirtualMachinePool { @@ -131,19 +143,18 @@ class VirtualMachinePoolTest : public PoolTest CPPUNIT_TEST_SUITE_END (); protected: + NebulaTestVM * tester; + VirtualMachinePool * vmpool; void bootstrap(SqlDB* db) { - VirtualMachinePool::bootstrap(db); + // setUp overwritten }; PoolSQL* create_pool(SqlDB* db) { - // The VM pool needs a vector containing the vm hooks - vector vm_hooks; - vector restricted_attrs; - - return new VirtualMachinePoolFriend(db, vm_hooks, restricted_attrs); + // setUp overwritten + return vmpool; }; int allocate(int index) @@ -181,6 +192,32 @@ public: ~VirtualMachinePoolTest(){xmlCleanupParser();}; + void setUp() + { + create_db(); + + tester = new NebulaTestVM(); + + Nebula& neb = Nebula::instance(); + neb.start(); + + vmpool = neb.get_vmpool(); + pool = vmpool; + }; + + void tearDown() + { + // ----------------------------------------------------------- + // Stop the managers & free resources + // ----------------------------------------------------------- + + //XML Library + xmlCleanupParser(); + + delete_db(); + + delete tester; + }; /* ********************************************************************* */ /* ********************************************************************* */ From f2105549a7f5d60b4c0be3012adcd8585e1739a9 Mon Sep 17 00:00:00 2001 From: "Ruben S. Montero" Date: Sat, 28 Apr 2012 02:33:18 +0200 Subject: [PATCH 2/5] feature #1243: Scheduler makes use of the resched flag. Needs to get live/cold migration type from config --- src/scheduler/include/VirtualMachinePoolXML.h | 5 +- src/scheduler/include/VirtualMachineXML.h | 17 ++++++- src/scheduler/src/pool/HostPoolXML.cc | 2 +- .../src/pool/VirtualMachinePoolXML.cc | 51 ++++++++++++++----- src/scheduler/src/pool/VirtualMachineXML.cc | 33 ++++++++++-- src/scheduler/src/sched/Scheduler.cc | 13 +++-- 6 files changed, 91 insertions(+), 30 deletions(-) diff --git a/src/scheduler/include/VirtualMachinePoolXML.h b/src/scheduler/include/VirtualMachinePoolXML.h index 3fa2901812..e8c9f5e485 100644 --- a/src/scheduler/include/VirtualMachinePoolXML.h +++ b/src/scheduler/include/VirtualMachinePoolXML.h @@ -47,13 +47,14 @@ public: return static_cast(PoolXML::get(oid)); }; - int dispatch(int vid, int hid) const; + int dispatch(int vid, int hid, bool resched) const; protected: int get_suitable_nodes(vector& content) { - return get_nodes("/VM_POOL/VM", content); + return get_nodes("/VM_POOL/VM[STATE=1 or (LCM_STATE=3 and RESCHED=1)]", + content); }; virtual void add_object(xmlNodePtr node); diff --git a/src/scheduler/include/VirtualMachineXML.h b/src/scheduler/include/VirtualMachineXML.h index f677ae9671..befb264083 100644 --- a/src/scheduler/include/VirtualMachineXML.h +++ b/src/scheduler/include/VirtualMachineXML.h @@ -56,10 +56,19 @@ public: return gid; }; + int get_hid() const + { + return hid; + }; + + bool is_resched() const + { + return (resched == 1); + } + /** - * Adds a new share to the map of suitable shares to start this VM + * Adds a new host to the list of suitable hosts to start this VM * @param hid of the selected host - * @param hsid of the selected host share */ void add_host(int hid); @@ -151,6 +160,10 @@ protected: int uid; int gid; + int hid; + + int resched; + int memory; float cpu; diff --git a/src/scheduler/src/pool/HostPoolXML.cc b/src/scheduler/src/pool/HostPoolXML.cc index 5c6ab100eb..316cca5a2d 100644 --- a/src/scheduler/src/pool/HostPoolXML.cc +++ b/src/scheduler/src/pool/HostPoolXML.cc @@ -27,7 +27,7 @@ int HostPoolXML::set_up() if ( rc == 0 ) { oss.str(""); - oss << "Discovered Hosts (enabled):"; + oss << "Discovered Hosts (enabled):" << endl; map::iterator it; diff --git a/src/scheduler/src/pool/VirtualMachinePoolXML.cc b/src/scheduler/src/pool/VirtualMachinePoolXML.cc index 8dedf4fe8e..2428b41154 100644 --- a/src/scheduler/src/pool/VirtualMachinePoolXML.cc +++ b/src/scheduler/src/pool/VirtualMachinePoolXML.cc @@ -21,11 +21,13 @@ int VirtualMachinePoolXML::set_up() { ostringstream oss; int rc; + rc = PoolXML::set_up(); + if ( rc == 0 ) { oss.str(""); - oss << "Pending virtual machines :"; + oss << "Pending and rescheduling VMs:" << endl; map::iterator it; @@ -72,7 +74,7 @@ int VirtualMachinePoolXML::load_info(xmlrpc_c::value &result) -2, // VM from all users -1, // start_id (none) -1, // end_id (none) - 1); // in pending state + -1); // not in DONE state return 0; } catch (exception const& e) @@ -90,27 +92,48 @@ int VirtualMachinePoolXML::load_info(xmlrpc_c::value &result) /* -------------------------------------------------------------------------- */ -int VirtualMachinePoolXML::dispatch(int vid, int hid) const +int VirtualMachinePoolXML::dispatch(int vid, int hid, bool resched) const { ostringstream oss; xmlrpc_c::value deploy_result; - oss.str(""); - oss << "Dispatching virtual machine " << vid - << " to HID: " << hid; + if (resched == true) + { + oss << "Rescheduling "; + } + else + { + oss << "Dispatching "; + } + + oss << "virtual machine " << vid << " to host " << hid; NebulaLog::log("VM",Log::INFO,oss); try { - client->call( client->get_endpoint(), // serverUrl - "one.vm.deploy", // methodName - "sii", // arguments format - &deploy_result, // resultP - client->get_oneauth().c_str(), // argument 0 - vid, // argument 1 - hid // argument 2 - ); + //TODO Get live migration from config file + if (resched == true) + { + client->call(client->get_endpoint(), // serverUrl + "one.vm.migrate", // methodName + "siib", // arguments format + &deploy_result, // resultP + client->get_oneauth().c_str(), // argument 0 (AUTH) + vid, // argument 1 (VM) + hid, // argument 2 (HOST) + true); // argument 3 (LIVE) + } + else + { + client->call(client->get_endpoint(), // serverUrl + "one.vm.deploy", // methodName + "sii", // arguments format + &deploy_result, // resultP + client->get_oneauth().c_str(), // argument 0 (AUTH) + vid, // argument 1 (VM) + hid); // argument 2 (HOST) + } } catch (exception const& e) { diff --git a/src/scheduler/src/pool/VirtualMachineXML.cc b/src/scheduler/src/pool/VirtualMachineXML.cc index f4c0137ba1..2fd1ca2702 100644 --- a/src/scheduler/src/pool/VirtualMachineXML.cc +++ b/src/scheduler/src/pool/VirtualMachineXML.cc @@ -66,7 +66,29 @@ void VirtualMachineXML::init_attributes() else { requirements = ""; + } + + result = ((*this)["/VM/HISTORY_RECORDS/HISTORY/HID"]); + + if (result.size() > 0) + { + hid = atoi(result[0].c_str()); } + else + { + hid = -1; + } + + result = ((*this)["/VM/RESCHED"]); + + if (result.size() > 0) + { + resched = atoi(result[0].c_str()); + } + else + { + resched = 0; + } } /* -------------------------------------------------------------------------- */ @@ -87,13 +109,16 @@ VirtualMachineXML::~VirtualMachineXML() /* -------------------------------------------------------------------------- */ /* -------------------------------------------------------------------------- */ -void VirtualMachineXML::add_host(int hid) +void VirtualMachineXML::add_host(int host_id) { - VirtualMachineXML::Host * ss; + if (( resched == 1 && host_id != hid ) || ( resched == 0 )) + { + VirtualMachineXML::Host * ss; - ss = new VirtualMachineXML::Host(hid); + ss = new VirtualMachineXML::Host(host_id); - hosts.push_back(ss); + hosts.push_back(ss); + } } /* -------------------------------------------------------------------------- */ diff --git a/src/scheduler/src/sched/Scheduler.cc b/src/scheduler/src/sched/Scheduler.cc index 03a5cea226..9f1dfbdcb8 100644 --- a/src/scheduler/src/sched/Scheduler.cc +++ b/src/scheduler/src/sched/Scheduler.cc @@ -329,7 +329,6 @@ void Scheduler::match() const map pending_vms = vmpool->get_objects(); const map hosts = hpool->get_objects(); - for (vm_it=pending_vms.begin(); vm_it != pending_vms.end(); vm_it++) { vm = static_cast(vm_it->second); @@ -516,15 +515,15 @@ void Scheduler::dispatch() map host_vms; - oss << "Select hosts" << endl; - oss << "\tPRI\tHID" << endl; - oss << "\t-------------------" << endl; + oss << "Selected hosts:" << endl; for (vm_it=pending_vms.begin(); vm_it != pending_vms.end(); vm_it++) { vm = static_cast(vm_it->second); - oss << "Virtual Machine: " << vm->get_oid() << "\n" << *vm << endl; + oss << "\t PRI\tHID VM: " << vm->get_oid() << endl + << "\t-----------------------" << endl + << *vm << endl; } NebulaLog::log("SCHED",Log::INFO,oss); @@ -541,9 +540,9 @@ void Scheduler::dispatch() if (rc == 0) { - rc = vmpool->dispatch(vm_it->first,hid); + rc = vmpool->dispatch(vm_it->first, hid, vm->is_resched()); - if (rc == 0) + if (rc == 0 && !vm->is_resched()) { dispatched_vms++; } From 38c5992cd85533f717bae096ef9fcc3d93ee8dea Mon Sep 17 00:00:00 2001 From: "Ruben S. Montero" Date: Sun, 29 Apr 2012 23:38:40 +0200 Subject: [PATCH 3/5] feature #1243: Add configuration option to select the rescheduling type --- src/scheduler/etc/sched.conf | 4 ++++ src/scheduler/include/Scheduler.h | 5 +++++ src/scheduler/include/VirtualMachinePoolXML.h | 17 +++++++++++++---- src/scheduler/src/pool/VirtualMachinePoolXML.cc | 2 +- src/scheduler/src/sched/Scheduler.cc | 7 +++++-- src/scheduler/src/sched/SchedulerTemplate.cc | 7 +++++++ 6 files changed, 35 insertions(+), 7 deletions(-) diff --git a/src/scheduler/etc/sched.conf b/src/scheduler/etc/sched.conf index b72f48dd37..73a4a91c6d 100644 --- a/src/scheduler/etc/sched.conf +++ b/src/scheduler/etc/sched.conf @@ -18,6 +18,8 @@ # MAX_HOST: Maximum number of Virtual Machines dispatched to a given host in # each scheduling action # +# LIVE_RESCHEDS: Perform live (1) or cold migrations (0) when rescheduling a VM +# # DEFAULT_SCHED: Definition of the default scheduling algorithm # - policy: # 0 = Packing. Heuristic that minimizes the number of hosts in use by @@ -41,6 +43,8 @@ MAX_DISPATCH = 30 MAX_HOST = 1 +LIVE_RESCHEDS = 0 + DEFAULT_SCHED = [ policy = 1 ] diff --git a/src/scheduler/include/Scheduler.h b/src/scheduler/include/Scheduler.h index 454f62fddd..6c7c09d8f7 100644 --- a/src/scheduler/include/Scheduler.h +++ b/src/scheduler/include/Scheduler.h @@ -155,6 +155,11 @@ private: */ unsigned int host_dispatch_limit; + /** + * Type of migrations when rescheduling a VM: 0 cold, 1 live + */ + unsigned int live_rescheds; + /** * Threshold value to round up freecpu */ diff --git a/src/scheduler/include/VirtualMachinePoolXML.h b/src/scheduler/include/VirtualMachinePoolXML.h index e8c9f5e485..b2b97e169b 100644 --- a/src/scheduler/include/VirtualMachinePoolXML.h +++ b/src/scheduler/include/VirtualMachinePoolXML.h @@ -27,10 +27,10 @@ class VirtualMachinePoolXML : public PoolXML { public: - VirtualMachinePoolXML( - Client* client, - unsigned int machines_limit - ):PoolXML(client, machines_limit){}; + VirtualMachinePoolXML(Client* client, + unsigned int machines_limit, + bool _live_resched): + PoolXML(client, machines_limit), live_resched(_live_resched){}; ~VirtualMachinePoolXML(){}; @@ -47,6 +47,12 @@ public: return static_cast(PoolXML::get(oid)); }; + /** + * 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 + */ int dispatch(int vid, int hid, bool resched) const; protected: @@ -60,6 +66,9 @@ protected: virtual void add_object(xmlNodePtr node); virtual int load_info(xmlrpc_c::value &result); + + /* Do live migrations to resched VMs*/ + bool live_resched; }; #endif /* VM_POOL_XML_H_ */ diff --git a/src/scheduler/src/pool/VirtualMachinePoolXML.cc b/src/scheduler/src/pool/VirtualMachinePoolXML.cc index 2428b41154..1b4852cb69 100644 --- a/src/scheduler/src/pool/VirtualMachinePoolXML.cc +++ b/src/scheduler/src/pool/VirtualMachinePoolXML.cc @@ -122,7 +122,7 @@ int VirtualMachinePoolXML::dispatch(int vid, int hid, bool resched) const client->get_oneauth().c_str(), // argument 0 (AUTH) vid, // argument 1 (VM) hid, // argument 2 (HOST) - true); // argument 3 (LIVE) + live_resched); // argument 3 (LIVE) } else { diff --git a/src/scheduler/src/sched/Scheduler.cc b/src/scheduler/src/sched/Scheduler.cc index 9f1dfbdcb8..28fd93725a 100644 --- a/src/scheduler/src/sched/Scheduler.cc +++ b/src/scheduler/src/sched/Scheduler.cc @@ -136,6 +136,8 @@ void Scheduler::start() conf.get("MAX_DISPATCH", dispatch_limit); conf.get("MAX_HOST", host_dispatch_limit); + + conf.get("LIVE_RESCHEDS", live_rescheds); oss.str(""); @@ -169,8 +171,9 @@ void Scheduler::start() // ----------------------------------------------------------- hpool = new HostPoolXML(client); - vmpool = new VirtualMachinePoolXML(client, machines_limit); - + vmpool = new VirtualMachinePoolXML(client, + machines_limit, + (live_rescheds == 1)); acls = new AclXML(client); // ----------------------------------------------------------- diff --git a/src/scheduler/src/sched/SchedulerTemplate.cc b/src/scheduler/src/sched/SchedulerTemplate.cc index 6e2c72f83a..c6aa61fc7d 100644 --- a/src/scheduler/src/sched/SchedulerTemplate.cc +++ b/src/scheduler/src/sched/SchedulerTemplate.cc @@ -40,6 +40,7 @@ void SchedulerTemplate::set_conf_default() # MAX_DISPATCH # MAX_HOST # DEFAULT_SCHED +# LIVE_RESCHEDS #------------------------------------------------------------------------------- */ // ONED_PORT @@ -71,6 +72,12 @@ 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 map vvalue; From f64fccdaad5755249116832d89b8c9e029da5389 Mon Sep 17 00:00:00 2001 From: "Ruben S. Montero" Date: Sun, 29 Apr 2012 23:41:34 +0200 Subject: [PATCH 4/5] feature #1243: Do not store uneeded vars in Scheduler class --- src/scheduler/include/Scheduler.h | 5 ----- src/scheduler/src/sched/Scheduler.cc | 8 +++++--- 2 files changed, 5 insertions(+), 8 deletions(-) diff --git a/src/scheduler/include/Scheduler.h b/src/scheduler/include/Scheduler.h index 6c7c09d8f7..454f62fddd 100644 --- a/src/scheduler/include/Scheduler.h +++ b/src/scheduler/include/Scheduler.h @@ -155,11 +155,6 @@ private: */ unsigned int host_dispatch_limit; - /** - * Type of migrations when rescheduling a VM: 0 cold, 1 live - */ - unsigned int live_rescheds; - /** * Threshold value to round up freecpu */ diff --git a/src/scheduler/src/sched/Scheduler.cc b/src/scheduler/src/sched/Scheduler.cc index 28fd93725a..d40bb1740b 100644 --- a/src/scheduler/src/sched/Scheduler.cc +++ b/src/scheduler/src/sched/Scheduler.cc @@ -65,15 +65,17 @@ extern "C" void * scheduler_action_loop(void *arg) void Scheduler::start() { - int rc; + int rc; ifstream file; ostringstream oss; string etc_path; - int oned_port; - pthread_attr_t pattr; + int oned_port; + unsigned int live_rescheds; + + pthread_attr_t pattr; // ----------------------------------------------------------- // Log system & Configuration File From 00b09519fd6c72413526488b93dc11facea65c84 Mon Sep 17 00:00:00 2001 From: "Ruben S. Montero" Date: Tue, 1 May 2012 23:17:22 +0200 Subject: [PATCH 5/5] feature #1243: Seting/Clearing resched flag requires ADMIN permissions. Bring back Sconstruct tests. --- SConstruct | 30 +++++++++++++------------- include/RequestManagerVirtualMachine.h | 11 ++++++---- src/rm/RequestManagerVirtualMachine.cc | 26 ++++++++++++++-------- 3 files changed, 39 insertions(+), 28 deletions(-) diff --git a/SConstruct b/SConstruct index c5db663582..cf962f4d85 100644 --- a/SConstruct +++ b/SConstruct @@ -237,22 +237,22 @@ if testing=='yes': ]) build_scripts.extend([ -# 'src/authm/test/SConstruct', -# 'src/common/test/SConstruct', -# 'src/host/test/SConstruct', -# 'src/cluster/test/SConstruct', -# 'src/datastore/test/SConstruct', -# 'src/group/test/SConstruct', -# 'src/image/test/SConstruct', -# 'src/lcm/test/SConstruct', -# 'src/pool/test/SConstruct', -# 'src/template/test/SConstruct', -# 'src/test/SConstruct', -# 'src/um/test/SConstruct', + 'src/authm/test/SConstruct', + 'src/common/test/SConstruct', + 'src/host/test/SConstruct', + 'src/cluster/test/SConstruct', + 'src/datastore/test/SConstruct', + 'src/group/test/SConstruct', + 'src/image/test/SConstruct', + 'src/lcm/test/SConstruct', + 'src/pool/test/SConstruct', + 'src/template/test/SConstruct', + 'src/test/SConstruct', + 'src/um/test/SConstruct', 'src/vm/test/SConstruct', -# 'src/vnm/test/SConstruct', -# 'src/xml/test/SConstruct', -# 'src/vm_template/test/SConstruct', + 'src/vnm/test/SConstruct', + 'src/xml/test/SConstruct', + 'src/vm_template/test/SConstruct', ]) else: main_env.Append(testing='no') diff --git a/include/RequestManagerVirtualMachine.h b/include/RequestManagerVirtualMachine.h index 6b5472807e..2955bbd79b 100644 --- a/include/RequestManagerVirtualMachine.h +++ b/include/RequestManagerVirtualMachine.h @@ -49,10 +49,11 @@ protected: RequestAttributes& att) = 0; bool vm_authorization(int id, - ImageTemplate * tmpl, - RequestAttributes& att, - PoolObjectAuth * host_perms, - PoolObjectAuth * ds_perm); + ImageTemplate * tmpl, + RequestAttributes& att, + PoolObjectAuth * host_perms, + PoolObjectAuth * ds_perm, + AuthRequest::Operation op); int get_host_information(int hid, string& name, string& vmm, string& vnm, RequestAttributes& att, PoolObjectAuth& host_perms); @@ -73,6 +74,8 @@ protected: class VirtualMachineAction : public RequestManagerVirtualMachine { public: + //auth_op is MANAGE for all actions but "resched" and "unresched" + //this is dynamically set for each request in the execute method VirtualMachineAction(): RequestManagerVirtualMachine("VirtualMachineAction", "Performs an action on a virtual machine", diff --git a/src/rm/RequestManagerVirtualMachine.cc b/src/rm/RequestManagerVirtualMachine.cc index cc8d129704..b252330b84 100644 --- a/src/rm/RequestManagerVirtualMachine.cc +++ b/src/rm/RequestManagerVirtualMachine.cc @@ -22,10 +22,11 @@ /* -------------------------------------------------------------------------- */ bool RequestManagerVirtualMachine::vm_authorization(int oid, - ImageTemplate * tmpl, - RequestAttributes& att, - PoolObjectAuth * host_perm, - PoolObjectAuth * ds_perm) + ImageTemplate * tmpl, + RequestAttributes& att, + PoolObjectAuth * host_perm, + PoolObjectAuth * ds_perm, + AuthRequest::Operation op) { PoolObjectSQL * object; PoolObjectAuth vm_perms; @@ -52,7 +53,7 @@ bool RequestManagerVirtualMachine::vm_authorization(int oid, AuthRequest ar(att.uid, att.gid); - ar.add_auth(auth_op, vm_perms); + ar.add_auth(op, vm_perms); if (host_perm != 0) { @@ -184,7 +185,14 @@ void VirtualMachineAction::request_execute(xmlrpc_c::paramList const& paramList, Nebula& nd = Nebula::instance(); DispatchManager * dm = nd.get_dm(); - if ( vm_authorization(id, 0, att, 0, 0) == false ) + AuthRequest::Operation op = auth_op; + + if (action == "resched" || action == "unresched") + { + op = AuthRequest::ADMIN; + } + + if ( vm_authorization(id, 0, att, 0, 0, op) == false ) { return; } @@ -297,7 +305,7 @@ void VirtualMachineDeploy::request_execute(xmlrpc_c::paramList const& paramList, return; } - auth = vm_authorization(id, 0, att, &host_perms, 0); + auth = vm_authorization(id, 0, att, &host_perms, 0, auth_op); if ( auth == false ) { @@ -359,7 +367,7 @@ void VirtualMachineMigrate::request_execute(xmlrpc_c::paramList const& paramList return; } - auth = vm_authorization(id, 0, att, &host_perms, 0); + auth = vm_authorization(id, 0, att, &host_perms, 0, auth_op); if ( auth == false ) { @@ -531,7 +539,7 @@ void VirtualMachineSaveDisk::request_execute(xmlrpc_c::paramList const& paramLis // Authorize the operation // ------------------------------------------------------------------------- - if ( vm_authorization(id, itemplate, att, 0, &ds_perms) == false ) + if ( vm_authorization(id, itemplate, att, 0, &ds_perms, auth_op) == false ) { delete itemplate; return;