1
0
mirror of https://github.com/OpenNebula/one.git synced 2025-03-22 18:50:08 +03:00

feature #3028: Scheduler check and set PCI device requests

This commit is contained in:
Ruben S. Montero 2015-08-21 17:23:08 +02:00
parent 2b7a2e9915
commit b1baa06f2b
7 changed files with 95 additions and 43 deletions

View File

@ -18,7 +18,8 @@
#include <iostream>
#include <sstream>
#include <algorithm>
#include <stdexcept>
#include <iomanip>
#include "HostShare.h"
@ -258,16 +259,22 @@ ostream& operator<<(ostream& os, const HostSharePCI& pci)
{
map<string, HostSharePCI::PCIDevice *>::const_iterator it;
os << right << setw(15)<< "PCI ADDRESS"<< " "
<< right << setw(8) << "CLASS" << " "
<< right << setw(8) << "VENDOR" << " "
<< right << setw(8) << "DEVICE" << " "
<< right << setw(8) << "VMID" << " "
<< endl << setw(55) << setfill('-') << "-" << setfill(' ') << endl;
for (it=pci.pci_devices.begin(); it!=pci.pci_devices.end(); it++)
{
HostSharePCI::PCIDevice * dev = it->second;
os << endl << "CLASS : " << dev->class_id;
os << endl << "VENDOR : " << dev->vendor_id;
os << endl << "DEVICE : " << dev->device_id;
os << endl << "ADDRESS : " << dev->address;
os << endl << "VMID : " << dev->vmid;
os << endl;
os << right << setw(15)<< dev->address << " "
<< right << setw(8) << dev->class_id << " "
<< right << setw(8) << dev->vendor_id << " "
<< right << setw(8) << dev->device_id << " "
<< right << setw(8) << dev->vmid << " " << endl;
}
return os;

View File

@ -51,21 +51,24 @@ public:
* Tests whether a new VM can be hosted by the host or not
* @param cpu needed by the VM (percentage)
* @param mem needed by the VM (in KB)
* @param pci devices needed byt the VM
* @param error error message
* @return true if the share can host the VM
*/
bool test_capacity(long long cpu, long long mem, string & error) const;
bool test_capacity(long long cpu, long long mem, vector<Attribute *> &pci,
string & error);
/**
* Tests whether a new VM can be hosted by the host or not
* @param cpu needed by the VM (percentage)
* @param mem needed by the VM (in KB)
* @param pci devices needed byt the VM
* @return true if the share can host the VM
*/
bool test_capacity(long long cpu, long long mem) const
bool test_capacity(long long cpu,long long mem,vector<Attribute *> &p)
{
string tmp_st;
return test_capacity(cpu, mem, tmp_st);
return test_capacity(cpu, mem, p, tmp_st);
};
/**
@ -75,11 +78,14 @@ public:
* @param mem needed by the VM (in KB)
* @return 0 on success
*/
void add_capacity(long long cpu, long long mem)
void add_capacity(int vmid, long long cpu, long long mem,
vector<Attribute *> &p)
{
cpu_usage += cpu;
mem_usage += mem;
pci.add(p, vmid);
running_vms++;
};

View File

@ -116,7 +116,8 @@ public:
return ds_requirements;
}
void get_requirements (int& cpu, int& memory, long long& disk);
void get_requirements (int& cpu, int& memory, long long& disk,
vector<Attribute *> &pci);
map<int,long long> get_storage_usage();

View File

@ -16,6 +16,8 @@
#include <math.h>
#include <sstream>
#include <stdexcept>
#include <iomanip>
#include "HostXML.h"
#include "NebulaUtil.h"
@ -125,30 +127,46 @@ int HostXML::search(const char *name, int& value)
/* -------------------------------------------------------------------------- */
/* -------------------------------------------------------------------------- */
bool HostXML::test_capacity(long long cpu, long long mem, string & error) const
bool HostXML::test_capacity(long long cpu, long long mem,
vector<Attribute *>& p, string & error)
{
bool fits = (((max_cpu - cpu_usage ) >= cpu) &&
((max_mem - mem_usage ) >= mem));
bool pci_fits = pci.test(p);
bool fits = ((max_cpu - cpu_usage ) >= cpu) &&
((max_mem - mem_usage ) >= mem) &&
pci_fits;
if (!fits)
{
if (NebulaLog::log_level() >= Log::DDEBUG)
{
ostringstream oss;
if ( pci_fits )
{
ostringstream oss;
oss << "Not enough capacity. "
<< "Requested: "
<< cpu << " CPU, "
<< mem << " KB MEM; "
<< "Available: "
<< (max_cpu - cpu_usage ) << " CPU, "
<< (max_mem - mem_usage ) << " KB MEM";
oss << "Not enough capacity. "
<< "Requested: "
<< cpu << " CPU, "
<< mem << " KB MEM; "
<< "Available: "
<< (max_cpu - cpu_usage ) << " CPU, "
<< (max_mem - mem_usage ) << " KB MEM";
error = oss.str();
error = oss.str();
}
else
{
error = "Unavailable PCI device.";
}
}
else
{
error = "Not enough capacity.";
if ( pci_fits )
{
error = "Not enough capacity.";
}
else
{
error = "Unavailable PCI device.";
}
}
}
@ -198,16 +216,18 @@ ostream& operator<<(ostream& o, const HostXML& p)
o << "RUNNING_VMS : " << p.running_vms << endl;
o << "PUBLIC : " << p.public_cloud << endl;
o << "DATASTORES" << endl;
o << "----------" << endl;
o << endl
<< right << setw(5) << "DSID" << " "
<< right << setw(15) << "FREE_MB" << " "
<< endl << setw(30) << setfill('-') << "-" << setfill (' ') << endl;
for (it = p.ds_free_disk.begin() ; it != p.ds_free_disk.end() ; it++)
{
o <<"\tDSID: "<< it->first << "\t\tFREE_MB: " << it->second << endl;
o << right << setw(5) << it->first << " "
<< right << setw(15)<< it->second<< " " << endl;
}
o << "PCI DEVICES"<< endl;
o << "-----------"<< endl;
o << p.pci;
o << endl << p.pci;
return o;
}

View File

@ -39,6 +39,7 @@ int VirtualMachinePoolXML::set_up()
<< right << setw(8) << "VM" << " "
<< right << setw(4) << "CPU" << " "
<< right << setw(11) << "Memory" << " "
<< right << setw(2) << "PCI" << " "
<< right << setw(11) << "System DS" << " "
<< " Image DS"
<< endl << setw(60) << setfill('-') << "-" << setfill(' ');
@ -47,11 +48,13 @@ int VirtualMachinePoolXML::set_up()
{
int cpu, mem;
long long disk;
vector<Attribute *> pci;
string action = "DEPLOY";
VirtualMachineXML * vm = static_cast<VirtualMachineXML *>(it->second);
vm->get_requirements(cpu, mem, disk);
vm->get_requirements(cpu, mem, disk, pci);
if (vm->is_resched())
{
@ -67,6 +70,7 @@ int VirtualMachinePoolXML::set_up()
<< right << setw(8) << it->first << " "
<< right << setw(4) << cpu << " "
<< right << setw(11) << mem << " "
<< right << setw(2) << pci.size() << " "
<< right << setw(11) << disk << " ";
map<int,long long> ds_usage = vm->get_storage_usage();

View File

@ -202,8 +202,18 @@ ostream& operator<<(ostream& os, VirtualMachineXML& vm)
/* -------------------------------------------------------------------------- */
/* -------------------------------------------------------------------------- */
void VirtualMachineXML::get_requirements (int& cpu, int& memory, long long& disk)
void VirtualMachineXML::get_requirements (int& cpu, int& memory,
long long& disk, vector<Attribute *> &pci)
{
if (vm_template != 0)
{
vm_template->get("PCI", pci);
}
else
{
pci.clear();
}
if (this->memory == 0 || this->cpu == 0)
{
cpu = 0;

View File

@ -502,6 +502,7 @@ int Scheduler::set_up_pools()
* @param vm the virtual machine
* @param vm_memory vm requirement
* @param vm_cpu vm requirement
* @param vm_pci vm requirement
* @param host to evaluate vm assgiment
* @param n_auth number of hosts authorized for the user, incremented if needed
* @param n_error number of requirement errors, incremented if needed
@ -511,8 +512,8 @@ int Scheduler::set_up_pools()
* @return true for a positive match
*/
static bool match_host(AclXML * acls, VirtualMachineXML* vm, int vmem, int vcpu,
HostXML * host, int &n_auth, int& n_error, int &n_fits, int &n_matched,
string &error)
vector<Attribute *>& vpci, HostXML * host, int &n_auth, int& n_error,
int &n_fits, int &n_matched, string &error)
{
// -------------------------------------------------------------------------
// Filter current Hosts for resched VMs
@ -560,7 +561,7 @@ static bool match_host(AclXML * acls, VirtualMachineXML* vm, int vmem, int vcpu,
// -------------------------------------------------------------------------
// Check host capacity
// -------------------------------------------------------------------------
if (host->test_capacity(vcpu,vmem,error) != true)
if (host->test_capacity(vcpu, vmem, vpci, error) != true)
{
return false;
}
@ -720,6 +721,7 @@ void Scheduler::match_schedule()
int vm_memory;
int vm_cpu;
long long vm_disk;
vector<Attribute *> vm_pci;
int n_resources;
int n_matched;
@ -750,7 +752,7 @@ void Scheduler::match_schedule()
{
vm = static_cast<VirtualMachineXML*>(vm_it->second);
vm->get_requirements(vm_cpu,vm_memory,vm_disk);
vm->get_requirements(vm_cpu, vm_memory, vm_disk, vm_pci);
n_resources = 0;
n_fits = 0;
@ -790,8 +792,8 @@ void Scheduler::match_schedule()
{
host = static_cast<HostXML *>(h_it->second);
if (match_host(acls, vm, vm_memory, vm_cpu, host, n_auth, n_error,
n_fits, n_matched, m_error))
if (match_host(acls, vm, vm_memory, vm_cpu, vm_pci, host, n_auth,
n_error, n_fits, n_matched, m_error))
{
vm->add_match_host(host->get_hid());
@ -1026,6 +1028,8 @@ void Scheduler::dispatch()
int cpu, mem;
long long dsk;
vector<Attribute *> pci;
int hid, dsid, cid;
bool test_cap_result;
@ -1074,7 +1078,7 @@ void Scheduler::dispatch()
}
}
vm->get_requirements(cpu,mem,dsk);
vm->get_requirements(cpu, mem, dsk, pci);
//----------------------------------------------------------------------
// Get the highest ranked host and best System DS for it
@ -1094,7 +1098,7 @@ void Scheduler::dispatch()
//------------------------------------------------------------------
// Test host capacity
//------------------------------------------------------------------
if (host->test_capacity(cpu,mem) != true)
if (host->test_capacity(cpu, mem, pci) != true)
{
continue;
}
@ -1224,7 +1228,7 @@ void Scheduler::dispatch()
vm->add_image_datastore_capacity(img_dspool);
}
host->add_capacity(cpu,mem);
host->add_capacity(vm->get_oid(), cpu, mem, pci);
host_vms[hid]++;