diff --git a/src/scheduler/include/ClusterPoolXML.h b/src/scheduler/include/ClusterPoolXML.h index f92f4303d1..f249a25177 100644 --- a/src/scheduler/include/ClusterPoolXML.h +++ b/src/scheduler/include/ClusterPoolXML.h @@ -42,6 +42,11 @@ public: return static_cast(PoolXML::get(oid)); }; + /** + * Identifier for the "none" cluster + */ + static const int NONE_CLUSTER_ID; + protected: int get_suitable_nodes(vector& content) diff --git a/src/scheduler/include/DatastoreXML.h b/src/scheduler/include/DatastoreXML.h index 4f0a806228..e4dffa31d2 100644 --- a/src/scheduler/include/DatastoreXML.h +++ b/src/scheduler/include/DatastoreXML.h @@ -62,6 +62,11 @@ public: return oid; }; + int get_cid() const + { + return cluster_id; + }; + private: int oid; diff --git a/src/scheduler/src/pool/ClusterPoolXML.cc b/src/scheduler/src/pool/ClusterPoolXML.cc index 9635c8ca5d..3beb483f30 100644 --- a/src/scheduler/src/pool/ClusterPoolXML.cc +++ b/src/scheduler/src/pool/ClusterPoolXML.cc @@ -16,6 +16,8 @@ #include "ClusterPoolXML.h" +const int ClusterPoolXML::NONE_CLUSTER_ID = -1; + void ClusterPoolXML::add_object(xmlNodePtr node) { if ( node == 0 || node->children == 0 ) diff --git a/src/scheduler/src/sched/Scheduler.cc b/src/scheduler/src/sched/Scheduler.cc index 18c6ad0f1e..fef47d68ae 100644 --- a/src/scheduler/src/sched/Scheduler.cc +++ b/src/scheduler/src/sched/Scheduler.cc @@ -14,11 +14,9 @@ /* limitations under the License. */ /* -------------------------------------------------------------------------- */ - #include #include - #include #include #include @@ -726,14 +724,14 @@ void Scheduler::dispatch() ostringstream oss; int cpu, mem, dsk; - int hid, dsid; + int hid, dsid, cid; unsigned int dispatched_vms = 0; map host_vms; pair::iterator, bool> rc; - vector::const_reverse_iterator i; + vector::const_reverse_iterator i, j; const map pending_vms = vmpool->get_objects(); //-------------------------------------------------------------------------- @@ -766,99 +764,124 @@ void Scheduler::dispatch() vm->get_requirements(cpu,mem,dsk); //---------------------------------------------------------------------- - // Get the highest ranked host + // Get the highest ranked host and best System DS for it //---------------------------------------------------------------------- const vector resources = vm->get_match_hosts(); - hid = -1; - for (i = resources.rbegin() ; i != resources.rend() ; i++) { - host = hpool->get((*i)->oid); + hid = (*i)->oid; + host = hpool->get(hid); if ( host == 0 ) { continue; } - if (host->test_capacity(cpu,mem,dsk) == true) - { - rc = host_vms.insert(make_pair((*i)->oid,0)); + cid = host->get_cid(); - //Select the host: update capacity and dispatch counter - if (rc.first->second < host_dispatch_limit) - { - host->add_capacity(cpu,mem,dsk); - - hid = (*i)->oid; - - rc.first->second++; - - break; - } - } - } - - if ( hid == -1 ) //No hosts for this VM skip DS selection and move on - { - continue; - } - - //---------------------------------------------------------------------- - // Migrate VM if reschedule VM, skip DS selection - //---------------------------------------------------------------------- - - if (vm->is_resched()) - { - vmpool->dispatch(vm_it->first, hid, -1, true); - } - - //---------------------------------------------------------------------- - // Get the highest ranked datastore - //---------------------------------------------------------------------- - const vector ds_resources = vm->get_match_datastores(); - - dsid = -1; - - for (i = ds_resources.rbegin() ; i != ds_resources.rend() ; i++) - { - ds = dspool->get((*i)->oid); - - if ( ds == 0 ) + //------------------------------------------------------------------ + // Test host capcity + //------------------------------------------------------------------ + if (host->test_capacity(cpu,mem,dsk) != true) { continue; } - if (ds->test_capacity(dsk)) - { - dsid = (*i)->oid; + //------------------------------------------------------------------ + // Test host dispatch limit (init counter if needed) + //------------------------------------------------------------------ + rc = host_vms.insert(make_pair(hid,0)); - ds->add_capacity(dsk); + if (rc.first->second >= host_dispatch_limit) + { + continue; + } + + //------------------------------------------------------------------ + // Migrate VM if reschedule VM, skip DS selection + //------------------------------------------------------------------ + if (vm->is_resched()) + { + host->add_capacity(cpu,mem,dsk); + + host_vms[hid]++; + + vmpool->dispatch(vm_it->first, hid, -1, true); //migrate VM break; } - } - if (dsid == -1) //No DS, rollback and go for the next VM - { - host = hpool->get(hid); + //------------------------------------------------------------------ + // Get the highest ranked datastore + //------------------------------------------------------------------ + const vector ds_resources = vm->get_match_datastores(); - if ( host != 0 ) + dsid = -1; + + for (j = ds_resources.rbegin() ; j != ds_resources.rend() ; j++) { - host->del_capacity(cpu,mem,dsk); + ds = dspool->get((*j)->oid); - host_vms[hid] = host_vms[hid] - 1; + if ( ds == 0 ) + { + continue; + } + + //-------------------------------------------------------------- + // Test cluster membership for datastore and selected host + //-------------------------------------------------------------- + if ((ds->get_cid() != ClusterPoolXML::NONE_CLUSTER_ID) && + (ds->get_cid() != cid)) + { + continue; + } + + //-------------------------------------------------------------- + // Test datastore capcity + //-------------------------------------------------------------- + if (ds->test_capacity(dsk) != true) + { + continue; + } + + //-------------------------------------------------------------- + //Select this DS to dispatch VM + //-------------------------------------------------------------- + dsid = (*j)->oid; + + break; } - continue; - } + if (dsid == -1) + { + ostringstream oss; + + oss << "No suitable System DS found for Host: " << hid + << ". Filtering out host."; + + NebulaLog::log("SCHED", Log::INFO, oss); + + continue; + } + + //------------------------------------------------------------------ + // Dispatch and update host and DS capacity, and dispatch counters + //------------------------------------------------------------------ + if (vmpool->dispatch(vm_it->first, hid, dsid, false) != 0) + { + continue; + } + + ds->add_capacity(dsk); + + host->add_capacity(cpu,mem,dsk); + + host_vms[hid]++; - //---------------------------------------------------------------------- - // Dispatch the VM - //---------------------------------------------------------------------- - if (vmpool->dispatch(vm_it->first, hid, dsid, false) == 0) - { dispatched_vms++; + + break; } } }