From d5deaaf9e48c0eb16364bea62dbdae27219977f5 Mon Sep 17 00:00:00 2001 From: "Ruben S. Montero" Date: Tue, 27 May 2014 17:19:36 +0200 Subject: [PATCH] feature #2858: First version of VNET reservation. VNET is created, addresses allocated. Needs to set free addr methods upon reservation removal. --- include/AddressRange.h | 102 ++++++++++---- include/AddressRangePool.h | 55 +++++++- include/RequestManagerVirtualNetwork.h | 26 ++++ include/VirtualNetwork.h | 86 +++++++++--- src/cli/one_helper/onevnet_helper.rb | 18 ++- src/cli/onevnet | 27 ++++ src/oca/ruby/opennebula/virtual_network.rb | 18 ++- src/rm/RequestManager.cc | 2 + src/rm/RequestManagerVirtualNetwork.cc | 146 ++++++++++++++++++++- src/vnm/AddressRange.cc | 103 +++++++++++++++ src/vnm/AddressRangePool.cc | 46 +++++++ src/vnm/VirtualNetwork.cc | 18 +++ 12 files changed, 596 insertions(+), 51 deletions(-) diff --git a/include/AddressRange.h b/include/AddressRange.h index e0c6526a64..dc030e8464 100644 --- a/include/AddressRange.h +++ b/include/AddressRange.h @@ -38,6 +38,40 @@ public: virtual ~AddressRange(){}; + // ************************************************************************* + // Address Range types + // ************************************************************************* + + /** + * Type of Addresses defined by this address range + */ + enum AddressType + { + NONE = 0x00000000, /** Undefined Address Type */ + ETHER = 0x00000001, /** MAC address type */ + IP4 = 0x00000003, /** IP version 4 address */ + IP6 = 0x00000005, /** IP version 6 address */ + IP4_6 = 0x00000007 /** IP dual stack version 4 & 6 addresses */ + }; + + /** + * Return the string representation of an AddressType + * @param ob the type + * @return the string + */ + static string type_to_str(AddressType ob); + + /** + * Return the string representation of an AddressType + * @param ob the type + * @return the string + */ + static AddressType str_to_type(string& str_type); + + // ************************************************************************* + // Address Range initialization functions + // ************************************************************************* + /** * Init an Address Range based on a vector attribute the following * attributes will be parsed (* are optional): @@ -84,31 +118,9 @@ public: */ void to_xml(ostringstream &oss) const; - /** - * Type of Addresses defined by this address range - */ - enum AddressType - { - NONE = 0x00000000, /** Undefined Address Type */ - ETHER = 0x00000001, /** MAC address type */ - IP4 = 0x00000003, /** IP version 4 address */ - IP6 = 0x00000005, /** IP version 6 address */ - IP4_6 = 0x00000007 /** IP dual stack version 4 & 6 addresses */ - }; - - /** - * Return the string representation of an AddressType - * @param ob the type - * @return the string - */ - static string type_to_str(AddressType ob); - - /** - * Return the string representation of an AddressType - * @param ob the type - * @return the string - */ - static AddressType str_to_type(string& str_type); + // ************************************************************************* + // Address allocation functions + // ************************************************************************* /** * Returns an unused address, which becomes used and fills a NIC attribute @@ -177,6 +189,38 @@ public: */ int free_addr_by_ip(PoolObjectSQL::ObjectType ot, int id, const string& ip); + /** + * Frees all previous allocated address to the given object + * @param ot the object type of the owner of the address + * @param obid the id of the owner of the address + * @return the number of addresses freed + */ + int free_addr_by_owner(PoolObjectSQL::ObjectType ot, int obid); + + // ************************************************************************* + // Address Reservation + // ************************************************************************* + + /** + * Reserve a given number of addresses from this address range + * @param pvid the id of the parent VNET + * @param vid the id of the VNET making the reservation + * @param size number of addresses to reserve + * @param rar a new address range to place the reservation + * @return 0 on success + */ + int reserve_addr(int pvid, int vid, unsigned int rsize, AddressRange *rar); + + /* + void reserve_addr_by_ip(); + + void reserve_addr_by_mac(); + */ + + // ************************************************************************* + // Helpers + // ************************************************************************* + /** * Return the id for this address range */ @@ -193,6 +237,14 @@ public: return used_addr; } + /** + * Return the number of free addresses + */ + unsigned int get_free_addr() const + { + return size - used_addr; + } + /** * Returns the string value of an Address Range Attribute * @param name of the attribute diff --git a/include/AddressRangePool.h b/include/AddressRangePool.h index cdf81b28a7..eb30cbce0a 100644 --- a/include/AddressRangePool.h +++ b/include/AddressRangePool.h @@ -37,6 +37,10 @@ public: virtual ~AddressRangePool(); + // ************************************************************************* + // Inititalization functions + // ************************************************************************* + /** * Builds the address range set from an array of VectorAttributes. This * function is used to create address ranges. @@ -54,6 +58,10 @@ public: */ int from_xml_node(const xmlNodePtr node); + // ************************************************************************* + // Address Range management interface + // ************************************************************************* + /** * Removes an address range from the pool if it does not contain any used * leases @@ -70,12 +78,14 @@ public: void update_ar(vector ars); /** - * Generate a XML representation of the Address Range Pool - * @param sstream where the ARPool is written - * @param extended true to include lease information - * @return the string with the XML + * Allocates a new address range in the pool. + * @return the new address range added to the pool */ - string& to_xml(string& sstream, bool extended) const; + AddressRange * allocate_ar(); + + // ************************************************************************* + // Address allocation interface + // ************************************************************************* /** * Allocates an address in a suitable address range from the pool @@ -182,6 +192,33 @@ public: */ void free_addr_by_ip(PoolObjectSQL::ObjectType ot, int id, const string& ip); + /** + * Frees all the addressed owned by the given object + * @param ot the type of the object requesting the address (VM or NET) + * @param obid the id of the object requesting the address + */ + void free_addr_by_owner(PoolObjectSQL::ObjectType ot, int obid); + + // ************************************************************************* + // Address reservation + // ************************************************************************* + + /** + * Reserve a given number of addresses from the first address range with + * enough free addresses to allocate the reservation + * @param pvid the id of the parent VNET + * @param vid the id of the VNET making the reservation + * @param size number of addresses to reserve + * @param rar a new address range to place the reservation + * @return 0 on success + */ + int reserve_addr(int pvid, int vid, unsigned int rsize, AddressRange *rar); + + + // ************************************************************************* + // Helpers & Formatting + // ************************************************************************* + /** * Return the number of used addresses */ @@ -198,6 +235,14 @@ public: */ void get_attribute(const char * name, string& value, int ar_id) const; + /** + * Generate a XML representation of the Address Range Pool + * @param sstream where the ARPool is written + * @param extended true to include lease information + * @return the string with the XML + */ + string& to_xml(string& sstream, bool extended) const; + private: /** * Stores the Address Ranges in a template form. This template is used diff --git a/include/RequestManagerVirtualNetwork.h b/include/RequestManagerVirtualNetwork.h index 918e73397b..29221933c0 100644 --- a/include/RequestManagerVirtualNetwork.h +++ b/include/RequestManagerVirtualNetwork.h @@ -49,6 +49,7 @@ protected: virtual int leases_action(VirtualNetwork * vn, VirtualNetworkTemplate * tmpl, + RequestAttributes& att, string& error_str) = 0; /* -------------------------------------------------------------------- */ @@ -68,6 +69,7 @@ public: int leases_action(VirtualNetwork * vn, VirtualNetworkTemplate * tmpl, + RequestAttributes& att, string& error_str) { return vn->add_ar(tmpl, error_str); @@ -109,6 +111,7 @@ public: int leases_action(VirtualNetwork * vn, VirtualNetworkTemplate * tmpl, + RequestAttributes& att, string& error_str) { error_str.clear(); @@ -132,6 +135,7 @@ public: int leases_action(VirtualNetwork * vn, VirtualNetworkTemplate * tmpl, + RequestAttributes& att, string& error_str) { return vn->hold_leases(tmpl, error_str); @@ -151,12 +155,34 @@ public: int leases_action(VirtualNetwork * vn, VirtualNetworkTemplate * tmpl, + RequestAttributes& att, string& error_str) { return vn->free_leases(tmpl, error_str); } }; +/* ------------------------------------------------------------------------- */ +/* ------------------------------------------------------------------------- */ + +class VirtualNetworkReserve: public Request +{ +public: + VirtualNetworkReserve():Request("VirtualNetworkReserve", "A:sis", + "Reserve network addresses") + { + Nebula& nd = Nebula::instance(); + pool = nd.get_vnpool(); + + auth_object = PoolObjectSQL::NET; + auth_op = AuthRequest::USE; + }; + + ~VirtualNetworkReserve(){}; + + void request_execute(xmlrpc_c::paramList const& _paramList, + RequestAttributes& att); +}; /* -------------------------------------------------------------------------- */ /* -------------------------------------------------------------------------- */ diff --git a/include/VirtualNetwork.h b/include/VirtualNetwork.h index f8a1dbb920..bfff9fc3ec 100644 --- a/include/VirtualNetwork.h +++ b/include/VirtualNetwork.h @@ -56,6 +56,10 @@ public: return new VirtualNetworkTemplate; } + // ************************************************************************* + // Address Range management interface + // ************************************************************************* + /** * Add an address range to the virtual network * @param ars_tmpl template in the form AR = [TYPE=...,IP=...,SIZE=...]. @@ -72,6 +76,15 @@ 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 + */ + AddressRange * allocate_ar() + { + return ar_pool.allocate_ar(); + } + /** * Update an address range to the virtual network * @param ars_tmpl template in the form AR = [AR_ID=...]. The address range @@ -79,6 +92,10 @@ public: */ void update_ar(VirtualNetworkTemplate * ars_tmpl); + // ************************************************************************* + // Address hold/release interface + // ************************************************************************* + /** * Holds a Lease, marking it as used * @param leases template in the form LEASES = [IP=XX]. @@ -98,6 +115,10 @@ public: */ int free_leases(VirtualNetworkTemplate* leases, string& error_msg); + // ************************************************************************* + // Address allocation funtions + // ************************************************************************* + /** * Gets a new address lease for a specific VM * @param vid VM identifier @@ -144,13 +165,51 @@ public: * @param arid of the address range where the address was leased from * @param vid the ID of the VM * @param mac MAC address identifying the lease - * @return 0 if success */ void free_addr(unsigned int arid, int vid, const string& mac) { ar_pool.free_addr(arid, PoolObjectSQL::VM, vid, mac); } + /** + * Release all previously given address leases to the given object + * @param ot the type of the object requesting the address (VM or NET) + * @param obid the id of the object requesting the address + */ + void free_addr_by_owner(PoolObjectSQL::ObjectType ot, int obid) + { + ar_pool.free_addr_by_owner(ot, obid); + } + + /** + * Modifies the given nic attribute adding the following attributes: + * * IP: leased from network + * * MAC: leased from network + * * BRIDGE: for this virtual network + * @param nic attribute for the VM template + * @param vid of the VM getting the lease + * @param inherit_attrs Attributes to be inherited from the vnet template + * into the nic + * @return 0 on success + */ + int nic_attribute( + VectorAttribute * nic, + int vid, + const vector& inherit_attrs); + + // ************************************************************************* + // Network Reservation functions + // ************************************************************************* + + int reserve_addr(VirtualNetwork *rvnet, unsigned int rsize, string& error_str); + + + + + // ************************************************************************* + // Formatting & Helper functions + // ************************************************************************* + /** * Gets used leases * @return number of network leases in used @@ -185,22 +244,6 @@ public: */ string& to_xml_extended(string& xml) const; - /** - * Modifies the given nic attribute adding the following attributes: - * * IP: leased from network - * * MAC: leased from network - * * BRIDGE: for this virtual network - * @param nic attribute for the VM template - * @param vid of the VM getting the lease - * @param inherit_attrs Attributes to be inherited from the vnet template - * into the nic - * @return 0 on success - */ - int nic_attribute( - VectorAttribute * nic, - int vid, - const vector& inherit_attrs); - /** * Replace the template of the virtual network it also updates the BRIDGE, * PHY_DEV, VLAN_ID and VLAN attributes. @@ -219,6 +262,15 @@ public: */ void get_template_attribute(const char * name, string& value, int ar_id) const; + /** + * @return A copy of the VNET Template + */ + VirtualNetworkTemplate * clone_template() const + { + return new VirtualNetworkTemplate( + *(static_cast(obj_template))); + }; + private: // ------------------------------------------------------------------------- diff --git a/src/cli/one_helper/onevnet_helper.rb b/src/cli/one_helper/onevnet_helper.rb index e834335560..79a0a702cb 100644 --- a/src/cli/one_helper/onevnet_helper.rb +++ b/src/cli/one_helper/onevnet_helper.rb @@ -66,6 +66,22 @@ class OneVNetHelper < OpenNebulaHelper::OneHelper :description => "IP6 ula prefix" } + R_NAME = { + :name => "rname", + :short => "-n reservation name", + :large => "--name reservation name", + :format => String, + :description => "Name of the address reservation" + } + + R_SIZE = { + :name => "rsize", + :short => "-s reservation size", + :large => "--size reservation size", + :format => String, + :description => "Number of addresses to reserve" + } + def self.rname "VNET" end @@ -240,7 +256,7 @@ class OneVNetHelper < OpenNebulaHelper::OneHelper if d['VM'] "VM : #{d['VM']}" elsif d['VNET'] - "NET: #{d['VM']}" + "NET: #{d['VNET']}" end end diff --git a/src/cli/onevnet b/src/cli/onevnet index fac9752c18..87f831b9e6 100755 --- a/src/cli/onevnet +++ b/src/cli/onevnet @@ -182,6 +182,33 @@ cmd=CommandParser::CmdParser.new(ARGV) do end end + reserve_desc = <<-EOT.unindent + Reserve addresses from the Virtual Network + EOT + + command :reserve, reserve_desc, :vnetid, + :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 + + if rsize == -1 + STDERR.puts "Specify a size (-s size) for the reservation" + exit -1 + end + + if rname == -1 + STDERR.puts "Specify a name (-n name) for the reservation" + exit -1 + end + + vn.reserve(rname, rsize) + end + end + + chgrp_desc = <<-EOT.unindent Changes the Virtual Network group EOT diff --git a/src/oca/ruby/opennebula/virtual_network.rb b/src/oca/ruby/opennebula/virtual_network.rb index 98a2d9435c..aeb52fc201 100644 --- a/src/oca/ruby/opennebula/virtual_network.rb +++ b/src/oca/ruby/opennebula/virtual_network.rb @@ -35,7 +35,8 @@ module OpenNebula :update => "vn.update", :hold => "vn.hold", :release => "vn.release", - :rename => "vn.rename" + :rename => "vn.rename", + :reserve => "vn.reserve" } # Creates a VirtualNetwork description with just its identifier @@ -185,6 +186,21 @@ module OpenNebula return rc end + # 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) + return Error.new('ID not defined') if !@pe_id + + rtmpl = "NAME = #{rname}\n" + rtmpl << "SIZE = #{rsize}\n" + + rc = @client.call(VN_METHODS[:reserve], @pe_id, rtmpl) + rc = nil if !OpenNebula.is_error?(rc) + + return rc + end + # Changes the owner/group # # @param uid [Integer] the new owner id. Set to -1 to leave the current one diff --git a/src/rm/RequestManager.cc b/src/rm/RequestManager.cc index 046f59c745..7b3dba92b8 100644 --- a/src/rm/RequestManager.cc +++ b/src/rm/RequestManager.cc @@ -281,6 +281,7 @@ void RequestManager::register_xml_methods() xmlrpc_c::methodPtr vn_update_ar(new VirtualNetworkUpdateAddressRange()); xmlrpc_c::methodPtr vn_hold(new VirtualNetworkHold()); xmlrpc_c::methodPtr vn_release(new VirtualNetworkRelease()); + xmlrpc_c::methodPtr vn_reserve(new VirtualNetworkReserve()); // Update Template Methods xmlrpc_c::methodPtr image_update(new ImageUpdateTemplate()); @@ -486,6 +487,7 @@ void RequestManager::register_xml_methods() RequestManagerRegistry.addMethod("one.groupquota.update", group_set_default_quota); /* Network related methods*/ + RequestManagerRegistry.addMethod("one.vn.reserve", vn_reserve); RequestManagerRegistry.addMethod("one.vn.add_ar", vn_add_ar); RequestManagerRegistry.addMethod("one.vn.rm_ar", vn_rm_ar); RequestManagerRegistry.addMethod("one.vn.update_ar", vn_update_ar); diff --git a/src/rm/RequestManagerVirtualNetwork.cc b/src/rm/RequestManagerVirtualNetwork.cc index d49afa7942..a6bec568b1 100644 --- a/src/rm/RequestManagerVirtualNetwork.cc +++ b/src/rm/RequestManagerVirtualNetwork.cc @@ -24,7 +24,7 @@ using namespace std; string RequestManagerVirtualNetwork::leases_error (const string& error) { - return request_error("Error modifying network leases",error); + return request_error("Error modifying network leases", error); } /* ------------------------------------------------------------------------- */ @@ -64,7 +64,7 @@ void RequestManagerVirtualNetwork:: return; } - rc = leases_action(vn,&tmpl,error_str); + rc = leases_action(vn, &tmpl, att, error_str); if ( rc < 0 ) { @@ -127,3 +127,145 @@ void VirtualNetworkRmAddressRange:: success_response(id, att); } + +/* ------------------------------------------------------------------------- */ +/* ------------------------------------------------------------------------- */ + +void VirtualNetworkReserve::request_execute( + xmlrpc_c::paramList const& paramList, RequestAttributes& att) +{ + int id = xmlrpc_c::value_int (paramList.getInt(1)); + string str_tmpl = xmlrpc_c::value_string (paramList.getString(2)); + + VirtualNetworkTemplate tmpl; + VirtualNetwork * vn; + + string error_str; + int rc; + + if ( basic_authorization(id, att) == false ) + { + return; + } + + // ----------------- Process the Reservation Template ------------------- + + rc = tmpl.parse_str_or_xml(str_tmpl, error_str); + + if ( rc != 0 ) + { + failure_response(ACTION, + request_error("Error in reservation request", error_str), att); + + return; + } + + int size; + + if ( !tmpl.get("SIZE", size) || size <= 0 ) + { + failure_response(ACTION, request_error("Error in reservation request", + "Reservation SIZE must be a greater than 0"), att); + + return; + } + + string name; + + tmpl.get("NAME", name); + + if (name.empty()) + { + failure_response(ACTION, request_error("Error in reservation request", + "NAME for reservation has to be set"), att); + + return; + } + + // --------------- Create a new VNET to place the reservation ------------- + + vn = static_cast(pool->get(id,true)); + + if ( vn == 0 ) + { + failure_response(NO_EXISTS, get_error(object_name(auth_object),id),att); + return; + } + + VirtualNetworkTemplate * vtmpl = vn->clone_template(); + + vtmpl->replace("NAME", name); + + int rid; + int cluster_id = vn->get_cluster_id(); + + rc = (static_cast(pool))->allocate(att.uid, att.gid, + att.uname, att.gname, att.umask, vtmpl, &rid, cluster_id, + vn->get_cluster_name(), error_str); + + if (rc < 0) + { + failure_response(INTERNAL, + request_error("Cannot allocate reservation VNET", error_str), att); + + vn->unlock(); + + return; + } + + VirtualNetwork * rvn = static_cast(pool->get(rid,true)); + + if (rvn == 0) + { + failure_response(INTERNAL, + request_error("Cannot allocate reservation VNET",""), att); + + vn->unlock(); + + return; + } + + // -------------- Make address reservation and set it ---------------------- + + if (vn->reserve_addr(rvn, size, error_str) != 0 ) + { + failure_response(ACTION, request_error(error_str,""), att); + + pool->drop(rvn, error_str); + + rvn->unlock(); + + vn->unlock(); + + return; + } + + pool->update(rvn); + + pool->update(vn); + + rvn->unlock(); + + vn->unlock(); + + // -------------- Add the reservation to the cluster ---------------------- + + if ( cluster_id != ClusterPool::NONE_CLUSTER_ID ) + { + Nebula& nd = Nebula::instance(); + + ClusterPool * clpool = nd.get_clpool(); + Cluster * cluster = clpool->get(cluster_id, true); + + if ( cluster != 0 ) + { + cluster->add_vnet(rid, error_str); + + clpool->update(cluster); + + cluster->unlock(); + } + } + + success_response(rid, att); +} diff --git a/src/vnm/AddressRange.cc b/src/vnm/AddressRange.cc index 876f3ce99d..d8d78bd021 100644 --- a/src/vnm/AddressRange.cc +++ b/src/vnm/AddressRange.cc @@ -178,6 +178,16 @@ int AddressRange::from_vattr(VectorAttribute *vattr, string& error_msg) vattr->replace("AR_ID", id); + vattr->remove("ALLOCATED"); + + vattr->remove("USED_LEASES"); + + vattr->remove("LEASES"); + + vattr->remove("PARENT_NETWORK_AR_ID"); + + vattr->remove("PARENT_NETWORK"); + if (do_mac) //Need to add MAC to the attribute { set_mac(0, attr); @@ -214,6 +224,10 @@ void AddressRange::update_attributes(VectorAttribute *vup) vup->remove("LEASES"); + vup->remove("PARENT_NETWORK_AR_ID"); + + vup->remove("PARENT_NETWORK"); + /* ----------------- update known attributes ----------------- */ unsigned int new_size; @@ -905,6 +919,38 @@ int AddressRange::free_addr_by_ip(PoolObjectSQL::ObjectType ot, int obid, /* -------------------------------------------------------------------------- */ /* -------------------------------------------------------------------------- */ +int AddressRange::free_addr_by_owner(PoolObjectSQL::ObjectType ot, int obid) +{ + map::iterator it = allocated.begin(); + + long long obj_pack = ot | (obid & 0x00000000FFFFFFFFLL); + + int freed = 0; + + while (it != allocated.end()) + { + if (it->second == obj_pack) + { + map::iterator prev_it = it++; + + allocated.erase(prev_it); + + used_addr--; + + freed++; + } + else + { + it++; + } + } + + return freed; +} + +/* -------------------------------------------------------------------------- */ +/* -------------------------------------------------------------------------- */ + int AddressRange::hold_by_ip(const string& ip_s) { if (!(type & 0x00000002))//Not of type IP4 or IP4_6 @@ -965,6 +1011,63 @@ int AddressRange::hold_by_mac(const string& mac_s) return 0; } +/* -------------------------------------------------------------------------- */ +/* -------------------------------------------------------------------------- */ + +int AddressRange::reserve_addr(int pvid, int vid, unsigned int rsize, + AddressRange *rar) +{ + bool isset = false; + unsigned int first_index; + int pnet; + + if (rsize > (size - used_addr)) + { + return -1; //reservation dosen't fit + } + + if ((attr->vector_value("PARENT_NETWORK_ID", pnet) == 0 ) && (pnet > -1)) + { + return -1; //This address range is already a reservation + } + + for ( unsigned int i=0; iclone(); + string errmsg; + + set_mac(first_index, new_ar); + + if (type & 0x00000002 ) + { + set_ip(first_index, new_ar); + } + + new_ar->replace("SIZE",rsize); + + rar->from_vattr(new_ar, errmsg); + + new_ar->replace("PARENT_NETWORK_ID", pvid); + + new_ar->replace("PARENT_NETWORK_AR_ID",id); + + return 0; +} + /* ************************************************************************** */ /* ************************************************************************** */ diff --git a/src/vnm/AddressRangePool.cc b/src/vnm/AddressRangePool.cc index 0c3ea6fd0a..3968ddd5a9 100644 --- a/src/vnm/AddressRangePool.cc +++ b/src/vnm/AddressRangePool.cc @@ -74,6 +74,18 @@ int AddressRangePool::from_vattr(vector ars, string& error_msg) /* -------------------------------------------------------------------------- */ /* -------------------------------------------------------------------------- */ +AddressRange * AddressRangePool::allocate_ar() +{ + AddressRange * ar = new AddressRange(next_ar); + + ar_pool.insert(make_pair(next_ar++, ar)); + + return ar; +} + +/* -------------------------------------------------------------------------- */ +/* -------------------------------------------------------------------------- */ + void AddressRangePool::update_ar(vector ars) { vector::iterator it; @@ -175,6 +187,7 @@ int AddressRangePool::rm_ar(unsigned int ar_id, string& error_msg) vector ars; vector::iterator it_ar; + Attribute * the_ar = 0; unsigned int ar_id_templ; @@ -369,6 +382,19 @@ void AddressRangePool::free_addr_by_ip(PoolObjectSQL::ObjectType ot, int obid, /* -------------------------------------------------------------------------- */ /* -------------------------------------------------------------------------- */ +void AddressRangePool::free_addr_by_owner(PoolObjectSQL::ObjectType ot, int oid) +{ + map::iterator it; + + for (it=ar_pool.begin(); it!=ar_pool.end(); it++) + { + used_addr = used_addr - it->second->free_addr_by_owner(ot, oid); + } +} + +/* -------------------------------------------------------------------------- */ +/* -------------------------------------------------------------------------- */ + void AddressRangePool::get_attribute(const char * name, string& value, int ar_id) const { @@ -471,3 +497,23 @@ int AddressRangePool::hold_by_mac(const string& mac_s) return rc; } +/* -------------------------------------------------------------------------- */ +/* -------------------------------------------------------------------------- */ + +int AddressRangePool::reserve_addr(int pvid, int vid, unsigned int rsize, + AddressRange *rar) +{ + map::iterator it; + + for (it=ar_pool.begin(); it!=ar_pool.end(); it++) + { + if ((it->second->get_free_addr() >= rsize) && + (it->second->reserve_addr(pvid, vid, rsize, rar) == 0)) + { + used_addr += rsize; + return 0; + } + } + + return -1; +} diff --git a/src/vnm/VirtualNetwork.cc b/src/vnm/VirtualNetwork.cc index 1d5db4bae6..b1b3696e59 100644 --- a/src/vnm/VirtualNetwork.cc +++ b/src/vnm/VirtualNetwork.cc @@ -766,3 +766,21 @@ void VirtualNetwork::get_template_attribute(const char * name, string& value, in PoolObjectSQL::get_template_attribute(name, value); } } + +/* -------------------------------------------------------------------------- */ +/* -------------------------------------------------------------------------- */ + +int VirtualNetwork::reserve_addr(VirtualNetwork *rvnet, + unsigned int rsize, string& error_str) +{ + AddressRange *rar = rvnet->allocate_ar(); + + if (ar_pool.reserve_addr(oid, rvnet->get_oid(), rsize, rar) != 0) + { + error_str = "Not enough free addresses in an address range"; + + return -1; + } + + return 0; +}