1
0
mirror of https://github.com/OpenNebula/one.git synced 2024-12-22 13:33:52 +03:00

Feature #1612: Add volatile disk quotas for attach/detach operations

This commit is contained in:
Carlos Martín 2013-10-15 13:45:16 +02:00
parent 37e065b7f7
commit b7234a4c37
6 changed files with 208 additions and 76 deletions

View File

@ -56,6 +56,16 @@ protected:
PoolObjectAuth * ds_perm,
AuthRequest::Operation op);
bool quota_resize_authorization(
Template * deltas,
RequestAttributes& att,
PoolObjectAuth& vm_perms);
bool quota_resize_authorization(
int oid,
Template * deltas,
RequestAttributes& att);
int get_host_information(
int hid,
string& name,

View File

@ -1073,6 +1073,11 @@ public:
*/
static bool isVolatile(const VectorAttribute * disk);
/**
* Check if the template contains a volatile disk
*/
static bool isVolatile(const Template * tmpl);
/**
* Return the total SIZE of volatile disks
*/

View File

@ -1346,12 +1346,21 @@ void LifeCycleManager::attach_failure_action(int vid)
tmpl.set(disk);
Quotas::quota_del(Quotas::IMAGE, uid, gid, &tmpl);
if ( disk->vector_value("IMAGE_ID", image_id) == 0 )
{
// Disk using an Image
Quotas::quota_del(Quotas::IMAGE, uid, gid, &tmpl);
imagem->release_image(oid, image_id, false);
}
else // Volatile disk
{
// It is an update of the volatile counter without
// shutting destroying a VM
tmpl.add("VMS", 0);
Quotas::quota_del(Quotas::VM, uid, gid, &tmpl);
}
}
}
else

View File

@ -96,6 +96,120 @@ bool RequestManagerVirtualMachine::vm_authorization(
/* -------------------------------------------------------------------------- */
/* -------------------------------------------------------------------------- */
bool RequestManagerVirtualMachine::quota_resize_authorization(
int oid,
Template * deltas,
RequestAttributes& att)
{
PoolObjectAuth vm_perms;
VirtualMachine * vm = Nebula::instance().get_vmpool()->get(oid, true);
if (vm == 0)
{
failure_response(NO_EXISTS,
get_error(object_name(PoolObjectSQL::VM),oid),
att);
return false;
}
vm->get_permissions(vm_perms);
vm->unlock();
return quota_resize_authorization(deltas, att, vm_perms);
}
/* -------------------------------------------------------------------------- */
/* -------------------------------------------------------------------------- */
bool RequestManagerVirtualMachine::quota_resize_authorization(
Template * deltas,
RequestAttributes& att,
PoolObjectAuth& vm_perms)
{
int rc;
string error_str;
Nebula& nd = Nebula::instance();
UserPool* upool = nd.get_upool();
GroupPool* gpool = nd.get_gpool();
Quotas user_dquotas = nd.get_default_user_quota();
Quotas group_dquotas = nd.get_default_group_quota();
if (vm_perms.uid != UserPool::ONEADMIN_ID)
{
User * user = upool->get(vm_perms.uid, true);
if ( user != 0 )
{
rc = user->quota.quota_update(Quotas::VM, deltas, user_dquotas, error_str);
if (rc == false)
{
ostringstream oss;
oss << object_name(PoolObjectSQL::USER)
<< " [" << vm_perms.uid << "] "
<< error_str;
failure_response(AUTHORIZATION,
request_error(oss.str(), ""),
att);
user->unlock();
return false;
}
upool->update(user);
user->unlock();
}
}
if (vm_perms.gid != GroupPool::ONEADMIN_ID)
{
Group * group = gpool->get(vm_perms.gid, true);
if ( group != 0 )
{
rc = group->quota.quota_update(Quotas::VM, deltas, group_dquotas, error_str);
if (rc == false)
{
ostringstream oss;
RequestAttributes att_tmp(vm_perms.uid, -1, att);
oss << object_name(PoolObjectSQL::GROUP)
<< " [" << vm_perms.gid << "] "
<< error_str;
failure_response(AUTHORIZATION,
request_error(oss.str(), ""),
att);
group->unlock();
quota_rollback(deltas, Quotas::VM, att_tmp);
return false;
}
gpool->update(group);
group->unlock();
}
}
return true;
}
/* -------------------------------------------------------------------------- */
/* -------------------------------------------------------------------------- */
int RequestManagerVirtualMachine::get_default_ds_information(
int cluster_id,
int& ds_id,
@ -1226,10 +1340,13 @@ void VirtualMachineAttach::request_execute(xmlrpc_c::paramList const& paramList,
DispatchManager * dm = nd.get_dm();
VirtualMachineTemplate * tmpl = new VirtualMachineTemplate();
VirtualMachineTemplate * deltas = 0;
PoolObjectAuth host_perms;
PoolObjectAuth vm_perms;
int rc;
string error_str;
bool volatile_disk;
int id = xmlrpc_c::value_int(paramList.getInt(1));
string str_tmpl = xmlrpc_c::value_string(paramList.getString(2));
@ -1258,17 +1375,43 @@ void VirtualMachineAttach::request_execute(xmlrpc_c::paramList const& paramList,
return;
}
volatile_disk = VirtualMachine::isVolatile(tmpl);
if ( volatile_disk )
{
deltas = new VirtualMachineTemplate(*tmpl);
deltas->add("VMS", 0);
if (quota_resize_authorization(id, deltas, att) == false)
{
delete tmpl;
delete deltas;
return;
}
}
else
{
if ( quota_authorization(tmpl, Quotas::IMAGE, att) == false )
{
delete tmpl;
return;
}
}
rc = dm->attach(id, tmpl, error_str);
if ( rc != 0 )
{
if ( volatile_disk )
{
quota_rollback(deltas, Quotas::VM, att);
}
else
{
quota_rollback(tmpl, Quotas::IMAGE, att);
}
failure_response(ACTION,
request_error(error_str, ""),
@ -1280,6 +1423,8 @@ void VirtualMachineAttach::request_execute(xmlrpc_c::paramList const& paramList,
}
delete tmpl;
delete deltas;
return;
}
@ -1338,13 +1483,7 @@ void VirtualMachineResize::request_execute(xmlrpc_c::paramList const& paramList,
int nvcpu, ovcpu;
Nebula& nd = Nebula::instance();
UserPool* upool = nd.get_upool();
GroupPool* gpool = nd.get_gpool();
HostPool * hpool = nd.get_hpool();
Quotas user_dquotas = nd.get_default_user_quota();
Quotas group_dquotas = nd.get_default_group_quota();
Host * host;
Template deltas;
@ -1494,71 +1633,11 @@ void VirtualMachineResize::request_execute(xmlrpc_c::paramList const& paramList,
/* Check quotas */
/* ---------------------------------------------------------------------- */
if (vm_perms.uid != UserPool::ONEADMIN_ID)
if (quota_resize_authorization(&deltas, att, vm_perms) == false)
{
User * user = upool->get(vm_perms.uid, true);
if ( user != 0 )
{
rc = user->quota.quota_update(Quotas::VM, &deltas, user_dquotas, error_str);
if (rc == false)
{
ostringstream oss;
oss << object_name(PoolObjectSQL::USER)
<< " [" << vm_perms.uid << "] "
<< error_str;
failure_response(AUTHORIZATION,
request_error(oss.str(), ""),
att);
user->unlock();
return;
}
upool->update(user);
user->unlock();
}
}
if (vm_perms.gid != GroupPool::ONEADMIN_ID)
{
Group * group = gpool->get(vm_perms.gid, true);
if ( group != 0 )
{
rc = group->quota.quota_update(Quotas::VM, &deltas, group_dquotas, error_str);
if (rc == false)
{
ostringstream oss;
RequestAttributes att_tmp(vm_perms.uid, -1, att);
oss << object_name(PoolObjectSQL::GROUP)
<< " [" << vm_perms.gid << "] "
<< error_str;
failure_response(AUTHORIZATION,
request_error(oss.str(), ""),
att);
group->unlock();
quota_rollback(&deltas, Quotas::VM, att_tmp);
return;
}
gpool->update(group);
group->unlock();
}
}
/* ---------------------------------------------------------------------- */
/* Check & update host capacity */
/* ---------------------------------------------------------------------- */

View File

@ -150,7 +150,9 @@ bool QuotaVirtualMachine::update(Template * tmpl,
vm_request.insert(make_pair("CPU", delta_cpu));
}
if ( tmpl->get("VOLATILE_SIZE", delta_size) == true )
delta_size = VirtualMachine::get_volatile_disk_size(tmpl);
if ( delta_size != 0 )
{
vm_request.insert(make_pair("VOLATILE_SIZE", delta_size));
}

View File

@ -2018,6 +2018,7 @@ VectorAttribute * VirtualMachine::delete_attach_disk()
return 0;
}
/* -------------------------------------------------------------------------- */
/* -------------------------------------------------------------------------- */
@ -2033,6 +2034,32 @@ bool VirtualMachine::isVolatile(const VectorAttribute * disk)
/* -------------------------------------------------------------------------- */
/* -------------------------------------------------------------------------- */
bool VirtualMachine::isVolatile(const Template * tmpl)
{
vector<const Attribute*> disks;
int num_disks = tmpl->get("DISK", disks);
for (int i = 0 ; i < num_disks ; i++)
{
const VectorAttribute * disk = dynamic_cast<const VectorAttribute*>(disks[i]);
if (disk == 0)
{
continue;
}
if (VirtualMachine::isVolatile(disk))
{
return true;
}
}
return false;
}
/* -------------------------------------------------------------------------- */
/* -------------------------------------------------------------------------- */
float VirtualMachine::get_volatile_disk_size(Template * tmpl)
{
float size = 0;