1
0
mirror of https://github.com/OpenNebula/one.git synced 2025-03-12 08:58:17 +03:00

feature #2858: Should prevent deadlocks in address reservations

This commit is contained in:
Ruben S. Montero 2014-06-09 12:07:09 +02:00
parent bf748659f6
commit 0d0bb093e0

View File

@ -202,6 +202,8 @@ void VirtualNetworkReserve::request_execute(
int rc;
int cluster_id;
PoolObjectAuth reserv_perms;
// -------------------------------------------------------------------------
// Process the Reservation Template
// -------------------------------------------------------------------------
@ -214,6 +216,8 @@ void VirtualNetworkReserve::request_execute(
return;
}
/* ------------------- Reservation SIZE ---------------- */
int size;
if ( !tmpl.get("SIZE", size) || size <= 0 )
@ -223,25 +227,73 @@ void VirtualNetworkReserve::request_execute(
return;
}
/* ------------------- Target reservation NETWORK_ID ---------------- */
int rid;
bool on_exisiting = tmpl.get("NETWORK_ID", rid);
if ( on_exisiting)
{
/* ------------------- Check reservation consistency ---------------- */
if (rid < 0)
{
failure_response(ACTION, request_error("Error in reservation request",
"NETWORK_ID must be equal or greater than 0"), att);
return;
}
else if (rid == id)
if (rid == id)
{
failure_response(ACTION, request_error("Error in reservation request",
"Cannot add a reservation from the same network"), att);
return;
}
rvn = vnpool->get(rid,true);
if (rvn == 0)
{
failure_response(NO_EXISTS, get_error(object_name(auth_object),rid),
att);
return;
}
int parent = rvn->get_parent();
if (parent == -1)
{
failure_response(ACTION, request_error("Error in reservation request",
"Cannot add reservations to a non-reservation VNET"), att);
rvn->unlock();
return;
}
if (parent != id)
{
ostringstream oss;
oss << "New reservations for virtual network " << rid
<< " have to be from network " << parent;
failure_response(ACTION, request_error("Error in reservation request",
oss.str()), att);
rvn->unlock();
return;
}
rvn->get_permissions(reserv_perms);
rvn->unlock();
}
/* ------------------- Reservation NAME ---------------- */
string name;
tmpl.get("NAME", name);
@ -253,6 +305,8 @@ void VirtualNetworkReserve::request_execute(
return;
}
/* ------------------- Starting AR_ID, IP & MAC ---------------- */
int ar_id;
bool with_ar_id = tmpl.get("AR_ID", ar_id);
@ -306,22 +360,6 @@ void VirtualNetworkReserve::request_execute(
if (on_exisiting)
{
rvn = vnpool->get(rid,true);
if (rvn == 0)
{
failure_response(NO_EXISTS, get_error(object_name(auth_object),rid),
att);
vn->unlock();
return;
}
PoolObjectAuth reserv_perms;
rvn->get_permissions(reserv_perms);
ar.add_auth(AuthRequest::MANAGE, reserv_perms);
}
@ -330,11 +368,6 @@ void VirtualNetworkReserve::request_execute(
failure_response(AUTHORIZATION, authorization_error(ar.message, att),
att);
if (on_exisiting)
{
rvn->unlock();
}
vn->unlock();
return;
@ -363,47 +396,14 @@ void VirtualNetworkReserve::request_execute(
return;
}
rvn = vnpool->get(rid, true);
if (rvn == 0)
{
failure_response(NO_EXISTS, get_error(object_name(auth_object),rid),
att);
vn->unlock();
return;
}
}
// -------------------------------------------------------------------------
// Check reservation consistency
// -------------------------------------------------------------------------
int parent = rvn->get_parent();
rvn = vnpool->get(rid, true);
if (parent == -1)
if (rvn == 0)
{
failure_response(ACTION, request_error("Cannot add reservations to a "
"non-reservation VNET",""), att);
rvn->unlock();
vn->unlock();
return;
}
if (on_exisiting && parent != id)
{
ostringstream oss;
oss << "New reservations for virtual network " << rid << " have to be "
<< "from network " << rvn->get_parent();
failure_response(ACTION, request_error(oss.str(),""), att);
rvn->unlock();
failure_response(NO_EXISTS, get_error(object_name(auth_object),rid),
att);
vn->unlock();