1
0
mirror of https://github.com/OpenNebula/one.git synced 2025-02-28 17:57:22 +03:00

feature #2858: Reserve by AR_ID, fix DB storage of reservations

This commit is contained in:
Ruben S. Montero 2014-05-29 12:44:41 +02:00
parent 1f09233b96
commit 977fc0d9e3
9 changed files with 167 additions and 13 deletions

View File

@ -22,6 +22,7 @@
#include <vector>
#include "PoolObjectSQL.h"
#include "AddressRangePool.h"
using namespace std;
@ -273,6 +274,12 @@ public:
*/
void update_attributes(VectorAttribute *vup);
/*
* add_ar from AddressRangePool needs to access the internal representation
* of the AR to include it in the ARPool template.
*/
friend int AddressRangePool::add_ar(AddressRange * ar);
private:
/* ---------------------------------------------------------------------- */
/* String to binary conversion functions for different address types */

View File

@ -24,9 +24,10 @@
#include <libxml/parser.h>
#include "Template.h"
#include "AddressRange.h"
#include "PoolObjectSQL.h"
class VectorAttribute;
class AddressRange;
using namespace std;
@ -78,11 +79,20 @@ public:
void update_ar(vector<Attribute *> ars);
/**
* Allocates a new address range in the pool.
* @return the new address range added to the pool
* Allocates a new *empty* address range. It is not added to the pool as it
* needs to be initialized. Only the AR_ID is set.
* @return the new address range.
*/
AddressRange * allocate_ar();
/**
* Adds a new address range to the pool. It should be allocated by the
* allocate_ar() function.
* @param ar the new address range;
* @return 0 on success
*/
int add_ar(AddressRange * ar);
// *************************************************************************
// Address allocation interface
// *************************************************************************
@ -214,6 +224,18 @@ public:
*/
int reserve_addr(int pvid, int vid, unsigned int rsize, AddressRange *rar);
/**
* Reserve a given number of addresses from the given address range
* @param pvid the id of the parent VNET
* @param vid the id of the VNET making the reservation
* @param rsize number of addresses to reserve
* @param ar_id the address range to reserve the addresses from
* @param rar a new address range to place the reservation
* @return 0 on success
*/
int reserve_addr(int pvid, int vid, unsigned int rsize, unsigned int ar_id,
AddressRange *rar);
/**
* Get the parent vnets of the Address Ranges in this AR POOL
* @param parent_vnets vector with the vnet ids of the parent vnets

View File

@ -77,14 +77,25 @@ public:
int rm_ar(unsigned int ar_id, string& error_msg);
/**
* Allocates a new (and empty) address range to the AR pool
* @return pointer to the ar added to the AR pool
* Allocates a new (and empty) address range. It is not added to the
* ar_pool
* @return pointer to the new address range
*/
AddressRange * allocate_ar()
{
return ar_pool.allocate_ar();
}
/**
* Adds a previously allocated address range to the AR pool
* @param rar pointer to the address range
* @return 0 on success
*/
int add_ar(AddressRange * rar)
{
return ar_pool.add_ar(rar);
}
/**
* Update an address range to the virtual network
* @param ars_tmpl template in the form AR = [AR_ID=...]. The address range
@ -203,6 +214,8 @@ public:
int reserve_addr(VirtualNetwork *rvnet, unsigned int rsize, string& error_str);
int reserve_addr(VirtualNetwork *rvnet, unsigned int rsize,
unsigned int ar_id, string& error_str);
// *************************************************************************
// Formatting & Helper functions

View File

@ -190,7 +190,6 @@ cmd=CommandParser::CmdParser.new(ARGV) do
:options=>STD_OPTIONS + [OneVNetHelper::AR, OneVNetHelper::R_NAME,
OneVNetHelper::R_SIZE] do
helper.perform_action(args[0],options,"reservation made") do |vn|
ar = options[:ar_id] || -1
rsize = options[:rsize] || -1
rname = options[:rname] || -1
@ -204,7 +203,7 @@ cmd=CommandParser::CmdParser.new(ARGV) do
exit -1
end
vn.reserve(rname, rsize)
vn.reserve(rname, rsize, options[:ar_id])
end
end

View File

@ -189,11 +189,13 @@ module OpenNebula
# Reserve a set of addresses from this virtual network
# @param name [String] of the reservation
# @param rsize[String] number of addresses to reserve
def reserve(rname, rsize)
# @param ar_id[String] the ar_id to make the reservation
def reserve(rname, rsize, ar_id)
return Error.new('ID not defined') if !@pe_id
rtmpl = "NAME = #{rname}\n"
rtmpl << "SIZE = #{rsize}\n"
rtmpl << "AR_ID= #{ar_id}\n" if !ar_id.nil?
rc = @client.call(VN_METHODS[:reserve], @pe_id, rtmpl)
rc = nil if !OpenNebula.is_error?(rc)

View File

@ -340,9 +340,11 @@ int VirtualNetworkDelete::drop(int oid, PoolObjectSQL * object, string& error_ms
int rc = RequestManagerDelete::drop(oid, object, error_msg);
VirtualNetworkPool *vnpool = static_cast<VirtualNetworkPool *>(pool);
for (vector<int>::iterator it = parents.begin(); it < parents.end(); it++)
{
vnet = static_cast<VirtualNetwork *>(pool->get(*it, true));
vnet = vnpool->get(*it, true);
if (vnet == 0)
{

View File

@ -182,6 +182,17 @@ void VirtualNetworkReserve::request_execute(
return;
}
int ar_id;
bool with_ar_id = tmpl.get("AR_ID", ar_id);
if ( with_ar_id && (ar_id < 0))
{
failure_response(ACTION, request_error("Error in reservation request",
"AR_ID must be equal or greater than 0"), att);
return;
}
// --------------- Check/update quotas on the target VNET -----------------
ostringstream qtmpl_s;
@ -250,7 +261,16 @@ void VirtualNetworkReserve::request_execute(
// -------------- Make address reservation and set it ----------------------
if (vn->reserve_addr(rvn, size, error_str) != 0 )
if (with_ar_id)
{
rc = vn->reserve_addr(rvn, size, ar_id, error_str);
}
else
{
rc = vn->reserve_addr(rvn, size, error_str);
}
if (rc != 0 )
{
quota_rollback(&qtmpl, Quotas::NETWORK, att);

View File

@ -15,6 +15,7 @@
/* -------------------------------------------------------------------------- */
#include "AddressRangePool.h"
#include "AddressRange.h"
using namespace std;
@ -76,11 +77,25 @@ int AddressRangePool::from_vattr(vector<Attribute *> ars, string& error_msg)
AddressRange * AddressRangePool::allocate_ar()
{
AddressRange * ar = new AddressRange(next_ar);
return new AddressRange(next_ar++);
}
ar_pool.insert(make_pair(next_ar++, ar));
/* -------------------------------------------------------------------------- */
return ar;
int AddressRangePool::add_ar(AddressRange * ar)
{
pair<map<unsigned int, AddressRange *>::iterator, bool> rc;
rc = ar_pool.insert(make_pair(ar->ar_id(), ar));
if (rc.second == false)
{
return -1;
}
ar_template.set(ar->attr);
return 0;
}
/* -------------------------------------------------------------------------- */
@ -497,6 +512,7 @@ int AddressRangePool::hold_by_mac(const string& mac_s)
return rc;
}
/* -------------------------------------------------------------------------- */
/* -------------------------------------------------------------------------- */
@ -521,6 +537,31 @@ int AddressRangePool::reserve_addr(int pvid, int vid, unsigned int rsize,
/* -------------------------------------------------------------------------- */
/* -------------------------------------------------------------------------- */
int AddressRangePool::reserve_addr(int pvid, int vid, unsigned int rsize,
unsigned int ar_id, AddressRange *rar)
{
map<unsigned int, AddressRange *>::iterator it;
it = ar_pool.find(ar_id);
if (it == ar_pool.end())
{
return -1;
}
if ((it->second->get_free_addr() >= rsize) &&
(it->second->reserve_addr(pvid, vid, rsize, rar) == 0))
{
used_addr += rsize;
return 0;
}
return -1;
}
/* -------------------------------------------------------------------------- */
/* -------------------------------------------------------------------------- */
unsigned int AddressRangePool::get_parents(vector<int>& parent_nets)
{
int vid;
@ -537,4 +578,6 @@ unsigned int AddressRangePool::get_parents(vector<int>& parent_nets)
num_parents++;
}
}
return num_parents;
}

View File

@ -18,6 +18,7 @@
#include "VirtualNetwork.h"
#include "VirtualNetworkPool.h"
#include "VirtualNetworkTemplate.h"
#include "AddressRange.h"
#include "NebulaLog.h"
@ -779,6 +780,51 @@ int VirtualNetwork::reserve_addr(VirtualNetwork *rvnet,
{
error_str = "Not enough free addresses in an address range";
delete rar;
return -1;
}
if (rvnet->add_ar(rar) != 0)
{
error_str = "Could not add the address range to the netwok";
delete rar;
return -1;
}
return 0;
}
/* -------------------------------------------------------------------------- */
/* -------------------------------------------------------------------------- */
int VirtualNetwork::reserve_addr(VirtualNetwork *rvnet,
unsigned int rsize, unsigned int ar_id, string& error_str)
{
AddressRange *rar = rvnet->allocate_ar();
if (ar_pool.reserve_addr(oid, rvnet->get_oid(), rsize, ar_id, rar) != 0)
{
ostringstream oss;
oss << "Not enough free addresses in address range " << ar_id
<< ", or it does not exist";
error_str = oss.str();
delete rar;
return -1;
}
if (rvnet->add_ar(rar) != 0)
{
error_str = "Could not add the address range to the netwok";
delete rar;
return -1;
}