From 7a67dc18b73ce1728ab7a219366cdf2d6a4c5569 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Carlos=20Mart=C3=ADn?= Date: Tue, 22 Oct 2013 13:32:37 +0200 Subject: [PATCH] Feature #1678: Scheduler tests free storage for Image DS also --- src/scheduler/include/VirtualMachineXML.h | 17 +++++ src/scheduler/src/pool/VirtualMachineXML.cc | 77 +++++++++++++++++++++ src/scheduler/src/sched/Scheduler.cc | 53 +++++++------- 3 files changed, 118 insertions(+), 29 deletions(-) diff --git a/src/scheduler/include/VirtualMachineXML.h b/src/scheduler/include/VirtualMachineXML.h index 814639074e..16e074e0c4 100644 --- a/src/scheduler/include/VirtualMachineXML.h +++ b/src/scheduler/include/VirtualMachineXML.h @@ -186,6 +186,23 @@ public: match_datastores.clear(); } + //-------------------------------------------------------------------------- + // Capacity Interface + //-------------------------------------------------------------------------- + + /** + * Tests if the Image DS have enough free space to host the VM + * @param img_datastores Image Datastores + * @return true if the Image Datastores can host the VM + */ + bool test_image_datastore_capacity(const map &img_datastores); + + /** + * Adds the VM disk requirements to each Image Datastore counter + * @param img_datastores Image Datastores + */ + void add_image_datastore_capacity(const map &img_datastores); + //-------------------------------------------------------------------------- // Action Interface //-------------------------------------------------------------------------- diff --git a/src/scheduler/src/pool/VirtualMachineXML.cc b/src/scheduler/src/pool/VirtualMachineXML.cc index 662892a987..4b508aa578 100644 --- a/src/scheduler/src/pool/VirtualMachineXML.cc +++ b/src/scheduler/src/pool/VirtualMachineXML.cc @@ -17,6 +17,7 @@ #include #include "VirtualMachineXML.h" +#include "DatastoreXML.h" #include "NebulaUtil.h" void VirtualMachineXML::init_attributes() @@ -403,3 +404,79 @@ int VirtualMachineXML::parse_action_name(string& action_st) return 0; }; + +/* -------------------------------------------------------------------------- */ +/* -------------------------------------------------------------------------- */ + +bool VirtualMachineXML::test_image_datastore_capacity(const map &img_datastores) +{ + map::const_iterator ds_it; + map::const_iterator ds_usage_it; + + ostringstream oss; + DatastoreXML* ds; + + for (ds_usage_it = ds_usage.begin(); ds_usage_it != ds_usage.end(); ds_usage_it++) + { + ds_it = img_datastores.find( ds_usage_it->first ); + + if (ds_it == img_datastores.end()) + { + oss << "VM " << oid + << ": Image Datastore " << ds_usage_it->first + << " is unknown for the Scheduler."; + + break; + } + + ds = static_cast( ds_it->second ); + + if (!ds->test_capacity(ds_usage_it->second)) + { + oss << "VM " << oid + << ": Image Datastore " << ds_usage_it->first + << " does not have enough free storage."; + + break; + } + } + + if (ds_usage_it != ds_usage.end()) + { + NebulaLog::log("SCHED",Log::INFO,oss); + + // TODO: log into VM template? +// log(oss.str()); + + return false; + } + + return true; +} + +/* -------------------------------------------------------------------------- */ +/* -------------------------------------------------------------------------- */ + +void VirtualMachineXML::add_image_datastore_capacity( + const map &img_datastores) +{ + map::const_iterator ds_it; + map::const_iterator ds_usage_it; + + DatastoreXML *ds; + + for (ds_usage_it = ds_usage.begin(); ds_usage_it != ds_usage.end(); ds_usage_it++) + { + ds_it = img_datastores.find( ds_usage_it->first ); + + if (ds_it == img_datastores.end()) + { + // TODO log error? + continue; + } + + ds = static_cast( ds_it->second ); + + ds->add_capacity(ds_usage_it->second); + } +} diff --git a/src/scheduler/src/sched/Scheduler.cc b/src/scheduler/src/sched/Scheduler.cc index 12593686d2..dce50185c9 100644 --- a/src/scheduler/src/sched/Scheduler.cc +++ b/src/scheduler/src/sched/Scheduler.cc @@ -408,8 +408,6 @@ void Scheduler::match_schedule() map::const_iterator vm_it; map::const_iterator h_it; - map::const_iterator ds_it; - map::const_iterator ds_usage_it; vector::iterator it; @@ -435,33 +433,15 @@ void Scheduler::match_schedule() n_auth = 0; n_error = 0; - map ds_usage = vm->get_storage_usage(); - - for (ds_usage_it = ds_usage.begin(); ds_usage_it != ds_usage.end(); ds_usage_it++) + //-------------------------------------------------------------- + // Test Image Datastore capacity, but not for migrations + //-------------------------------------------------------------- + if (!vm->is_resched()) { - ds_it = img_datastores.find( ds_usage_it->first ); - - if (ds_it == img_datastores.end()) + if (vm->test_image_datastore_capacity(img_datastores) == false) { - // TODO log error continue; } - - ds = static_cast( ds_it->second ); - - if (!ds->test_capacity(ds_usage_it->second)) - { - ostringstream oss; - - oss << "VM " << oid << " cannot be deployed because Datastore " - << ds_usage_it->first << " does not have enough free storage."; - - NebulaLog::log("SCHED",Log::INFO,oss); - - vm->log(oss.str()); - } - - break; } // --------------------------------------------------------------------- @@ -797,7 +777,9 @@ void Scheduler::dispatch() pair::iterator, bool> rc; vector::const_reverse_iterator i, j; - const map pending_vms = vmpool->get_objects(); + + const map pending_vms = vmpool->get_objects(); + const map img_datastores = img_dspool->get_objects(); //-------------------------------------------------------------------------- // Print the VMs to schedule and the selected hosts for each one @@ -826,12 +808,25 @@ void Scheduler::dispatch() { vm = static_cast(vm_it->second); + const vector resources = vm->get_match_hosts(); + + //-------------------------------------------------------------- + // Test Image Datastore capacity, but not for migrations + //-------------------------------------------------------------- + + if (!resources.empty() && !vm->is_resched()) + { + if (vm->test_image_datastore_capacity(img_datastores) == false) + { + continue; + } + } + vm->get_requirements(cpu,mem,dsk); //---------------------------------------------------------------------- // Get the highest ranked host and best System DS for it //---------------------------------------------------------------------- - const vector resources = vm->get_match_hosts(); for (i = resources.rbegin() ; i != resources.rend() ; i++) { @@ -959,12 +954,12 @@ void Scheduler::dispatch() { host->add_ds_capacity(ds->get_oid(), dsk); } + + vm->add_image_datastore_capacity(img_datastores); } host->add_capacity(cpu,mem); - // TODO update img DS free space - host_vms[hid]++; dispatched_vms++;