diff --git a/src/scheduler/include/HostXML.h b/src/scheduler/include/HostXML.h index cba3512d35..28df1b16cd 100644 --- a/src/scheduler/include/HostXML.h +++ b/src/scheduler/include/HostXML.h @@ -122,6 +122,15 @@ public: hypervisor_mem = 1.0 - mem; }; + /** + * Check if host is hybrid + * @return true if the host is enabled + */ + bool isHybrid() const + { + return hybrid; + } + private: int oid; int cluster_id; @@ -139,6 +148,9 @@ private: long long running_vms; /**< Number of running VMs in this Host */ + bool hybrid; + + // Configuration attributes static float hypervisor_mem; /**< Fraction of memory for the VMs */ static const char *host_paths[]; /**< paths for search function */ diff --git a/src/scheduler/include/VirtualMachineXML.h b/src/scheduler/include/VirtualMachineXML.h index eb5c9d8a2a..770a3d83e6 100644 --- a/src/scheduler/include/VirtualMachineXML.h +++ b/src/scheduler/include/VirtualMachineXML.h @@ -115,6 +115,15 @@ public: map get_storage_usage(); + /** + * Checks if VM is hybrid + * @return true if the VM is enabled + */ + bool isHybrid() const + { + return hybrid; + }; + //-------------------------------------------------------------------------- // Matched Resources Interface //-------------------------------------------------------------------------- @@ -188,6 +197,17 @@ public: match_datastores.clear(); } + /** + * Marks the VM to be only deployed on hybrid hosts + */ + void set_only_hybrid(); + + /** + * Returns true is the VM can only be deployed in hybrid hosts + * @return true is the VM can only be deployed in hybrid hosts + */ + bool is_only_hybrid() const; + //-------------------------------------------------------------------------- // Capacity Interface //-------------------------------------------------------------------------- @@ -282,6 +302,8 @@ protected: ResourceMatch match_datastores; + bool only_hybrid; + /* ----------------------- VIRTUAL MACHINE ATTRIBUTES ------------------- */ int oid; @@ -299,6 +321,8 @@ protected: map ds_usage; + bool hybrid; + string rank; string requirements; diff --git a/src/scheduler/src/pool/HostXML.cc b/src/scheduler/src/pool/HostXML.cc index c057b6bd3b..a0c07aa652 100644 --- a/src/scheduler/src/pool/HostXML.cc +++ b/src/scheduler/src/pool/HostXML.cc @@ -53,6 +53,9 @@ void HostXML::init_attributes() //Reserve memory for the hypervisor max_mem = static_cast(hypervisor_mem * static_cast(max_mem)); + vector hybrid_st_vector = (*this)["/HOST/TEMPLATE/HYBRID"]; + hybrid = ( hybrid_st_vector.size() > 0 && hybrid_st_vector[0] == "YES" ); + vector ds_ids = (*this)["/HOST/HOST_SHARE/DATASTORES/DS/ID"]; vector ds_free_mb = (*this)["/HOST/HOST_SHARE/DATASTORES/DS/FREE_MB"]; diff --git a/src/scheduler/src/pool/VirtualMachineXML.cc b/src/scheduler/src/pool/VirtualMachineXML.cc index 809ecf9367..217ea545cb 100644 --- a/src/scheduler/src/pool/VirtualMachineXML.cc +++ b/src/scheduler/src/pool/VirtualMachineXML.cc @@ -82,7 +82,7 @@ void VirtualMachineXML::init_attributes() ds_rank = result[0]; } - // ------------------- REQUIREMENTS & DS_REQUIREMENTS ---------------------- + // ------------------- HOST REQUIREMENTS ----------------------------------- result = ((*this)["/VM/TEMPLATE/AUTOMATIC_REQUIREMENTS"]); @@ -113,6 +113,8 @@ void VirtualMachineXML::init_attributes() requirements = automatic_requirements; } + // ------------------- DS REQUIREMENTS ------------------------------------- + result = ((*this)["/VM/USER_TEMPLATE/SCHED_DS_REQUIREMENTS"]); if (result.size() > 0) @@ -206,6 +208,21 @@ void VirtualMachineXML::init_attributes() { system_ds_usage = 0; } + + vector attrs; + user_template->get("HYBRID", attrs); + + hybrid = (attrs.size() > 0); + + if (hybrid == false) + { + attrs.clear(); + user_template->get("EC2", attrs); + + hybrid = (attrs.size() > 0); + } + + only_hybrid = false; } /* -------------------------------------------------------------------------- */ @@ -470,3 +487,26 @@ void VirtualMachineXML::add_image_datastore_capacity( ds->add_capacity(ds_usage_it->second); } } + +/* -------------------------------------------------------------------------- */ +/* -------------------------------------------------------------------------- */ + +void VirtualMachineXML::set_only_hybrid() +{ + only_hybrid = true; + + ostringstream oss; + + oss << "VM " << oid << ": Local Datastores do not have enough capacity. " + << "This VM can be only deployed in a Hybrid Host."; + + NebulaLog::log("SCHED",Log::INFO,oss); +} + +/* -------------------------------------------------------------------------- */ +/* -------------------------------------------------------------------------- */ + +bool VirtualMachineXML::is_only_hybrid() const +{ + return only_hybrid; +} diff --git a/src/scheduler/src/sched/Scheduler.cc b/src/scheduler/src/sched/Scheduler.cc index 02067ae977..7eb46f1fa3 100644 --- a/src/scheduler/src/sched/Scheduler.cc +++ b/src/scheduler/src/sched/Scheduler.cc @@ -439,7 +439,17 @@ void Scheduler::match_schedule() { if (vm->test_image_datastore_capacity(img_dspool) == false) { - continue; + if (vm->isHybrid()) + { + // Image DS do not have capacity, but if the VM ends + // in a hybrid host, image copies will not + // be performed. + vm->set_only_hybrid(); + } + else + { + continue; + } } } @@ -498,6 +508,20 @@ void Scheduler::match_schedule() n_auth++; + // ----------------------------------------------------------------- + // Check that VM can be deployed in local hosts + // ----------------------------------------------------------------- + if (vm->is_only_hybrid() && !host->isHybrid()) + { + ostringstream oss; + + oss << "VM " << oid << ": Host " << host->get_hid() + << " filtered out. VM can only be deployed in a Hybrid Host, but this one is local."; + + NebulaLog::log("SCHED",Log::DEBUG,oss); + continue; + } + // ----------------------------------------------------------------- // Evaluate VM requirements // ----------------------------------------------------------------- @@ -721,34 +745,44 @@ void Scheduler::match_schedule() // Log scheduling errors to VM user if any // --------------------------------------------------------------------- - if (n_hosts == 0) //No datastores assigned, let's see why + if (n_hosts == 0) { - if (n_error == 0) //No syntax error + // For a hybrid VM, 0 system DS is not a problem + if (vm->isHybrid()) { - if (datastores.size() == 0) - { - vm->log("No system datastores found to run VMs"); - } - else if (n_matched == 0) - { - ostringstream oss; - - oss << "No system datastore meets SCHED_DS_REQUIREMENTS: " - << ds_reqs; - - vm->log(oss.str()); - } - else - { - vm->log("No system datastore with enough capacity for the VM"); - } + vm->set_only_hybrid(); } + else + { + //No datastores assigned, let's see why - vm->clear_match_hosts(); + if (n_error == 0) //No syntax error + { + if (datastores.size() == 0) + { + vm->log("No system datastores found to run VMs"); + } + else if (n_matched == 0) + { + ostringstream oss; - vmpool->update(vm); + oss << "No system datastore meets SCHED_DS_REQUIREMENTS: " + << ds_reqs; - continue; + vm->log(oss.str()); + } + else + { + vm->log("No system datastore with enough capacity for the VM"); + } + } + + vm->clear_match_hosts(); + + vmpool->update(vm); + + continue; + } } // --------------------------------------------------------------------- @@ -826,7 +860,17 @@ void Scheduler::dispatch() { if (vm->test_image_datastore_capacity(img_dspool) == false) { - continue; + if (vm->isHybrid()) + { + // Image DS do not have capacity, but if the VM ends + // in a hybrid host, image copies will not + // be performed. + vm->set_only_hybrid(); + } + else + { + continue; + } } } @@ -849,13 +893,21 @@ void Scheduler::dispatch() cid = host->get_cid(); //------------------------------------------------------------------ - // Test host capcity + // Test host capacity //------------------------------------------------------------------ if (host->test_capacity(cpu,mem) != true) { continue; } + //------------------------------------------------------------------ + // Check that VM can be deployed in local hosts + //------------------------------------------------------------------ + if (vm->is_only_hybrid() && !host->isHybrid()) + { + continue; + } + //------------------------------------------------------------------ // Test host dispatch limit (init counter if needed) //------------------------------------------------------------------ @@ -873,7 +925,17 @@ void Scheduler::dispatch() dsid = -1; - for (j = ds_resources.rbegin() ; j != ds_resources.rend() ; j++) + // Skip the loop for hybrid hosts, they don't need a system DS + if (host->isHybrid()) + { + j = ds_resources.rend(); + } + else + { + j = ds_resources.rbegin(); + } + + for ( ; j != ds_resources.rend() ; j++) { ds = dspool->get((*j)->oid); @@ -930,7 +992,7 @@ void Scheduler::dispatch() break; } - if (dsid == -1) + if (dsid == -1 && !host->isHybrid()) { ostringstream oss; @@ -952,7 +1014,8 @@ void Scheduler::dispatch() } // DS capacity is only added for new deployments, not for migrations - if (!vm->is_resched()) + // It is also omitted for VMs deployed in hybrid hosts + if (!vm->is_resched() && !host->isHybrid()) { if (ds->is_shared() && ds->is_monitored()) {