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

feature #1233: Added quotas.Refactor Attach methods

This commit is contained in:
Ruben S. Montero 2012-06-15 12:28:20 +02:00
parent 554321c73b
commit 1dbeaa1719
14 changed files with 571 additions and 493 deletions

View File

@ -232,6 +232,7 @@ public:
* Set the re-scheduling flag for the VM (must be in RUNNING state)
* @param vid VirtualMachine identification
* @param do_resched set or unset the flag
*
* @return 0 on success, -1 if the VM does not exits or -2 if the VM is
* in a wrong a state
*/
@ -240,19 +241,14 @@ public:
bool do_resched);
/**
* Starts the attach disk action.
* Starts the attach disk action.
* @param vid VirtualMachine identification
* @param tmpl Template containing the new DISK attribute.
* @param error_str Error reason, if any
*
* @param vm pointer to a VirtualMachine with its mutex locked. It will be
* unlocked
* @param tmpl Template containing the new DISK attribute.
* It will be deleted
* @param error_str Error reason, if any
* @return 0 on success, -1 action error, -2 if the VM is in a wrong a state
* @return 0 on success, -1 otherwise
*/
int attach(
VirtualMachine * vm,
VirtualMachineTemplate * tmpl,
string & error_str);
int attach(int vid, VirtualMachineTemplate * tmpl, string & error_str);
private:
/**

View File

@ -22,6 +22,8 @@
#include "QuotaVirtualMachine.h"
#include "QuotaImage.h"
class ObjectXML;
class Quotas
{
public:
@ -44,52 +46,7 @@ public:
*
* @return 0 on success, -1 otherwise
*/
int set(Template *tmpl, string& error)
{
vector<Attribute *> vquotas;
if ( tmpl->get(datastore_quota.get_quota_name(), vquotas) > 0 )
{
if ( datastore_quota.set(&vquotas, error) != 0 )
{
return -1;
}
vquotas.clear();
}
if ( tmpl->get(network_quota.get_quota_name(), vquotas) > 0 )
{
if ( network_quota.set(&vquotas, error) != 0 )
{
return -1;
}
vquotas.clear();
}
if ( tmpl->get(image_quota.get_quota_name(), vquotas) > 0 )
{
if ( image_quota.set(&vquotas, error) != 0 )
{
return -1;
}
vquotas.clear();
}
if ( tmpl->get(vm_quota.get_quota_name(), vquotas) > 0 )
{
if ( vm_quota.set(&vquotas, error) != 0 )
{
return -1;
}
vquotas.clear();
}
return 0;
}
int set(Template *tmpl, string& error);
/**
* Check Datastore quotas, it updates usage counters if quotas are not
@ -159,76 +116,32 @@ public:
* @param xml the string to store the XML
* @return the same xml string to use it in << compounds
*/
string& to_xml(string& xml) const
{
ostringstream oss;
string ds_quota_xml;
string net_quota_xml;
string vm_quota_xml;
string image_quota_xml;
oss << datastore_quota.to_xml(ds_quota_xml)
<< network_quota.to_xml(net_quota_xml)
<< vm_quota.to_xml(vm_quota_xml)
<< image_quota.to_xml(image_quota_xml);
xml = oss.str();
return xml;
}
string& to_xml(string& xml) const;
/**
* Builds quota object from an ObjectXML
* @param object_xml pointer to the ObjectXML
* @return 0 if success
*/
int from_xml(ObjectXML * object_xml)
{
vector<xmlNodePtr> content;
int rc = 0;
int from_xml(ObjectXML * object_xml);
object_xml->get_nodes(ds_xpath, content);
/**
* Delete VM related usage (network, image and compute) from quota counters.
* for the given user and group
* @param uid of the user
* @param gid of the group
* @param tmpl template for the image, with usage
*/
static void vm_del(int uid, int gid, Template * tmpl);
if (!content.empty())
{
rc += datastore_quota.from_xml_node(content[0]);
}
object_xml->free_nodes(content);
content.clear();
object_xml->get_nodes(net_xpath, content);
if (!content.empty())
{
rc += network_quota.from_xml_node(content[0]);
}
object_xml->free_nodes(content);
content.clear();
object_xml->get_nodes(vm_xpath, content);
if (!content.empty())
{
rc += vm_quota.from_xml_node(content[0]);
}
object_xml->free_nodes(content);
content.clear();
object_xml->get_nodes(img_xpath, content);
if (!content.empty())
{
rc += image_quota.from_xml_node(content[0]);
}
object_xml->free_nodes(content);
return rc;
}
/**
* Delete Datastore related usage from quota counters.
* for the given user and group
* @param uid of the user
* @param gid of the group
* @param tmpl template for the image, with usage
*/
static void ds_del(int uid, int gid, Template * tmpl);
private:
//--------------------------------------------------------------------------
@ -238,17 +151,17 @@ private:
/**
* Datastore Quotas
*/
QuotaDatastore datastore_quota;
QuotaDatastore datastore_quota;
/**
* Network Quotas
*/
QuotaNetwork network_quota;
QuotaNetwork network_quota;
/**
* Image Quotas
*/
QuotaImage image_quota;
QuotaImage image_quota;
/**
* Virtual Machine Quotas

View File

@ -49,11 +49,12 @@ protected:
RequestAttributes& att) = 0;
bool vm_authorization(int id,
ImageTemplate * tmpl,
RequestAttributes& att,
PoolObjectAuth * host_perms,
PoolObjectAuth * ds_perm,
AuthRequest::Operation op);
ImageTemplate * tmpl,
VirtualMachineTemplate* vtmpl,
RequestAttributes& att,
PoolObjectAuth * host_perms,
PoolObjectAuth * ds_perm,
AuthRequest::Operation op);
int get_host_information(int hid, string& name, string& vmm, string& vnm,
RequestAttributes& att, PoolObjectAuth& host_perms);

View File

@ -169,6 +169,15 @@ public:
const string& name,
vector<Attribute *>& values);
/**
* Removes an attribute from the template, but it DOES NOT free the
* attribute.
* @param att Attribute to remove. It will be deleted
* @return pointer to the removed attribute or 0 if non attribute was
* removed
*/
virtual Attribute * remove(Attribute * att);
/**
* Removes an attribute from the template, and frees the attributes.
* @param name of the attribute

View File

@ -24,6 +24,7 @@
#include "NebulaLog.h"
#include <time.h>
#include <set>
#include <sstream>
using namespace std;
@ -744,17 +745,31 @@ public:
// ------------------------------------------------------------------------
/**
* Attaches a new disk. It will acquire the Image used, if any, and add the
* disk to the VM template. The VM must be updated in the DB afterwards.
*
* @param tmpl Template containing a single DISK vector attribute. The
* caller must delete this template
* @param error_str Returns the error reason, if any
*
* @return 0 on success
* Collects information about VM DISKS
* @param num_disks of the VM
* @param used_targets by the DISKS of the VM
*/
int attach_disk(VirtualMachineTemplate * tmpl, string& error_str);
void get_disk_info(int& num_disks, set<string>& used_targets);
/**
* Generate a DISK attributed to be attached to the VM.
* @param tmpl Template containing a single DISK vector attribute.
* @param used_targets targets in use by current DISKS
* @param num_disks of the VM
* @param uid of the VM owner
* @param image_id returns the id of the aquired image
* @param error_str describes the error
*
* @return a new vectorattribute with the DISK (should be freed if not
* added to the template), 0 in case of error;
*/
static VectorAttribute * set_up_attach_disk(
VirtualMachineTemplate * tmpl,
set<string>& used_targets,
int num_disks,
int uid,
int& image_id,
string& error_str);
/**
* Returns the disk that is waiting for an attachment action
*
@ -764,18 +779,27 @@ public:
/**
* Cleans the ATTACH = YES attribute from the disks
*
* @return 0 on success, -1 otherwise
*/
int attach_success();
void clear_attach_disk();
/**
* Deletes the DISK that was in the process of being attached, and releases
* the image, if any
* Deletes the DISK that was in the process of being attached
*
* @return 0 on success, -1 otherwise
* @return the DISK or 0 if no disk was deleted
*/
int attach_failure();
VectorAttribute * delete_attach_disk();
/**
* Adds a new disk to the virtual machine template. The disk should be
* generated by the build_attach_disk
* @param new_disk must be allocated in the heap
*/
void attach_disk(VectorAttribute * new_disk)
{
new_disk->replace("ATTACH", "YES");
obj_template->set(new_disk);
}
private:

View File

@ -685,9 +685,6 @@ int DispatchManager::finalize(
VirtualMachine * vm;
ostringstream oss;
Template * tmpl;
User * user;
Group * group;
int uid;
int gid;
@ -709,8 +706,6 @@ int DispatchManager::finalize(
Nebula& nd = Nebula::instance();
TransferManager * tm = nd.get_tm();
LifeCycleManager * lcm = nd.get_lcm();
UserPool * upool = nd.get_upool();
GroupPool * gpool = nd.get_gpool();
switch (state)
{
@ -739,34 +734,7 @@ int DispatchManager::finalize(
vm->unlock();
if ( uid != UserPool::ONEADMIN_ID )
{
user = upool->get(uid, true);
if ( user != 0 )
{
user->quota.vm_del(tmpl);
upool->update(user);
user->unlock();
}
}
if ( gid != GroupPool::ONEADMIN_ID )
{
group = gpool->get(gid, true);
if ( group != 0 )
{
group->quota.vm_del(tmpl);
gpool->update(group);
group->unlock();
}
}
Quotas::vm_del(uid, gid, tmpl);
delete tmpl;
break;
@ -845,59 +813,96 @@ int DispatchManager::resubmit(int vid)
/* -------------------------------------------------------------------------- */
/* -------------------------------------------------------------------------- */
int DispatchManager::attach(
VirtualMachine * vm,
VirtualMachineTemplate * tmpl,
string & error_str)
int DispatchManager::attach(int vid,
VirtualMachineTemplate * tmpl,
string & error_str)
{
ostringstream oss;
int rc;
int vid = vm->get_oid();
ostringstream oss;
Nebula& nd = Nebula::instance();
VirtualMachineManager * vmm = nd.get_vmm();
int num_disks;
int uid;
int image_id;
oss << "Attaching a new disk to VM " << vid;
NebulaLog::log("DiM",Log::DEBUG,oss);
set<string> used_targets;
VectorAttribute * disk;
Nebula& nd = Nebula::instance();
VirtualMachineManager* vmm = nd.get_vmm();
VirtualMachine * vm = vmpool->get(vid, true);
if ( vm == 0 )
{
oss << "VirtualMachine " << vid << " no longer exists";
return -1;
}
if ( vm->get_state() != VirtualMachine::ACTIVE ||
vm->get_lcm_state() != VirtualMachine::RUNNING )
{
goto error_state;
}
oss << "Could not attach a new disk to VM " << vid << ", wrong state.";
error_str = oss.str();
rc = vm->attach_disk(tmpl, error_str);
NebulaLog::log("DiM", Log::ERROR, error_str);
if ( rc != 0 )
{
goto error;
vm->unlock();
return -1;
}
vm->get_disk_info(num_disks, used_targets);
vm->set_state(VirtualMachine::HOTPLUG);
vm->set_resched(false);
uid = vm->get_uid();
vmpool->update(vm);
vm->unlock();
delete tmpl;
vmm->trigger(VirtualMachineManager::ATTACH,vid);
disk = VirtualMachine::set_up_attach_disk(tmpl,
used_targets,
num_disks,
uid,
image_id,
error_str);
vm = vmpool->get(vid, true);
if ( vm == 0 )
{
Nebula& nd = Nebula::instance();
ImageManager* imagem = nd.get_imagem();
if ( image_id != -1 )
{
imagem->release_image(image_id, false);
}
return -1;
}
if ( disk == 0 )
{
vm->set_state(VirtualMachine::RUNNING);
vmpool->update(vm);
vm->unlock();
return -1;
}
else
{
vm->attach_disk(disk);
}
vmpool->update(vm);
vm->unlock();
vmm->trigger(VirtualMachineManager::ATTACH,vid);
return 0;
error:
vm->unlock();
delete tmpl;
return -1;
error_state:
oss.str("");
oss << "Could not attach a new disk to VM " << vid << ", wrong state.";
error_str = oss.str();
NebulaLog::log("DiM", Log::ERROR, error_str);
vm->unlock();
delete tmpl;
return -2;
}

View File

@ -108,13 +108,6 @@ void DispatchManager::done_action(int vid)
VirtualMachine::LcmState lcm_state;
VirtualMachine::VmState dm_state;
Nebula& nd = Nebula::instance();
UserPool * upool = nd.get_upool();
GroupPool* gpool = nd.get_gpool();
User * user;
Group * group;
vm = vmpool->get(vid,true);
if ( vm == 0 )
@ -150,35 +143,7 @@ void DispatchManager::done_action(int vid)
vm->unlock();
/* ---------------- Update Group & User quota counters -------------- */
if ( uid != UserPool::ONEADMIN_ID )
{
user = upool->get(uid, true);
if ( user != 0 )
{
user->quota.vm_del(tmpl);
upool->update(user);
user->unlock();
}
}
if ( gid != GroupPool::ONEADMIN_ID )
{
group = gpool->get(gid, true);
if ( group != 0 )
{
group->quota.vm_del(tmpl);
gpool->update(group);
group->unlock();
}
}
Quotas::vm_del(uid, gid, tmpl);
delete tmpl;
}

View File

@ -274,13 +274,7 @@ int ImageManager::delete_image(int iid, const string& ds_data)
int uid;
int gid;
Group* group;
User * user;
Nebula& nd = Nebula::instance();
UserPool * upool = nd.get_upool();
GroupPool* gpool = nd.get_gpool();
img = ipool->get(iid,true);
if ( img == 0 )
@ -354,33 +348,7 @@ int ImageManager::delete_image(int iid, const string& ds_data)
img_usage.add("DATASTORE", ds_id);
img_usage.add("SIZE", size);
if ( uid != UserPool::ONEADMIN_ID )
{
user = upool->get(uid, true);
if ( user != 0 )
{
user->quota.ds_del(&img_usage);
upool->update(user);
user->unlock();
}
}
if ( gid != GroupPool::ONEADMIN_ID )
{
group = gpool->get(gid, true);
if ( group != 0 )
{
group->quota.ds_del(&img_usage);
gpool->update(group);
group->unlock();
}
}
Quotas::ds_del(uid, gid, &img_usage);
return 0;
}

View File

@ -846,7 +846,7 @@ void LifeCycleManager::attach_success_action(int vid)
return;
}
vm->attach_success();
vm->clear_attach_disk();
vm->set_state(VirtualMachine::RUNNING);
@ -860,7 +860,11 @@ void LifeCycleManager::attach_success_action(int vid)
void LifeCycleManager::attach_failure_action(int vid)
{
VirtualMachine * vm;
VirtualMachine * vm;
VectorAttribute * disk;
int uid;
int gid;
vm = vmpool->get(vid,true);
@ -869,7 +873,9 @@ void LifeCycleManager::attach_failure_action(int vid)
return;
}
vm->attach_failure();
disk = vm->delete_attach_disk();
uid = vm->get_uid();
gid = vm->get_gid();
vm->set_state(VirtualMachine::RUNNING);
@ -877,7 +883,14 @@ void LifeCycleManager::attach_failure_action(int vid)
vm->unlock();
// TODO: update quotas, here or in VirtualMachine::attach_failure
if ( disk != 0 )
{
Template tmpl;
tmpl.set(disk);
Quotas::vm_del(uid, gid, &tmpl);
}
}
/* -------------------------------------------------------------------------- */

View File

@ -22,12 +22,13 @@
/* -------------------------------------------------------------------------- */
bool RequestManagerVirtualMachine::vm_authorization(
int oid,
ImageTemplate * tmpl,
RequestAttributes& att,
PoolObjectAuth * host_perm,
PoolObjectAuth * ds_perm,
AuthRequest::Operation op)
int oid,
ImageTemplate * tmpl,
VirtualMachineTemplate* vtmpl,
RequestAttributes& att,
PoolObjectAuth * host_perm,
PoolObjectAuth * ds_perm,
AuthRequest::Operation op)
{
PoolObjectSQL * object;
PoolObjectAuth vm_perms;
@ -69,6 +70,11 @@ bool RequestManagerVirtualMachine::vm_authorization(
ar.add_create_auth(PoolObjectSQL::IMAGE, tmpl->to_xml(t_xml));
}
if ( vtmpl != 0 )
{
VirtualMachine::set_auth_request(att.uid, ar, vtmpl);
}
if ( ds_perm != 0 )
{
ar.add_auth(AuthRequest::USE, *ds_perm);
@ -196,7 +202,7 @@ void VirtualMachineAction::request_execute(xmlrpc_c::paramList const& paramList,
op = AuthRequest::ADMIN;
}
if ( vm_authorization(id, 0, att, 0, 0, op) == false )
if ( vm_authorization(id, 0, 0, att, 0, 0, op) == false )
{
return;
}
@ -313,7 +319,7 @@ void VirtualMachineDeploy::request_execute(xmlrpc_c::paramList const& paramList,
return;
}
auth = vm_authorization(id, 0, att, &host_perms, 0, auth_op);
auth = vm_authorization(id, 0, 0, att, &host_perms, 0, auth_op);
if ( auth == false )
{
@ -375,7 +381,7 @@ void VirtualMachineMigrate::request_execute(xmlrpc_c::paramList const& paramList
return;
}
auth = vm_authorization(id, 0, att, &host_perms, 0, auth_op);
auth = vm_authorization(id, 0, 0, att, &host_perms, 0, auth_op);
if ( auth == false )
{
@ -546,7 +552,7 @@ void VirtualMachineSaveDisk::request_execute(xmlrpc_c::paramList const& paramLis
// Authorize the operation & check quotas
// -------------------------------------------------------------------------
if ( vm_authorization(id, itemplate, att, 0, &ds_perms, auth_op) == false )
if ( vm_authorization(id, itemplate, 0, att, 0, &ds_perms, auth_op) == false )
{
delete itemplate;
return;
@ -598,7 +604,7 @@ void VirtualMachineMonitoring::request_execute(
ostringstream oss;
bool auth = vm_authorization(id, 0, att, 0, 0, auth_op);
bool auth = vm_authorization(id, 0, 0, att, 0, 0, auth_op);
if ( auth == false )
{
@ -624,59 +630,66 @@ void VirtualMachineMonitoring::request_execute(
void VirtualMachineAttach::request_execute(xmlrpc_c::paramList const& paramList,
RequestAttributes& att)
{
Nebula& nd = Nebula::instance();
DispatchManager * dm = nd.get_dm();
Nebula& nd = Nebula::instance();
DispatchManager * dm = nd.get_dm();
VirtualMachine * vm;
VirtualMachineTemplate * tmpl;
PoolObjectAuth host_perms;
VirtualMachine * vm;
VirtualMachineTemplate * tmpl = new VirtualMachineTemplate();
PoolObjectAuth host_perms;
int rc;
int rc;
string error_str;
int id = xmlrpc_c::value_int(paramList.getInt(1));
string str_tmpl = xmlrpc_c::value_string(paramList.getString(2));
tmpl = new VirtualMachineTemplate();
// -------------------------------------------------------------------------
// Parse Disk template
// -------------------------------------------------------------------------
rc = tmpl->parse_str_or_xml(str_tmpl, error_str);
rc = tmpl->parse_str_or_xml(str_tmpl, error_str);
if ( rc != 0 )
{
failure_response(INTERNAL, "", att); // TODO: error message
failure_response(INTERNAL, error_str, att);
delete tmpl;
return;
}
// TODO: auth & quotas
// TODO: set vm state HOTPLUG & vm->set_resched(false); // Cancel re-scheduling actions
vm = get_vm(id, att);
if ( vm == 0 )
// -------------------------------------------------------------------------
// Authorize the operation & check quotas
// -------------------------------------------------------------------------
if ( vm_authorization(id, 0, tmpl, att, 0, 0, auth_op) == false )
{
failure_response(NO_EXISTS,
get_error(object_name(auth_object),id),
att);
delete tmpl;
return;
}
rc = dm->attach(vm, tmpl, error_str);
if ( quota_authorization(tmpl, att) == false )
{
delete tmpl;
return;
}
rc = dm->attach(id, tmpl, error_str);
if ( rc != 0 )
{
quota_rollback(tmpl, att);
failure_response(ACTION,
request_error(error_str, ""),
att);
return;
}
else
{
success_response(id, att);
}
success_response(id, att);
delete tmpl;
return;
}
/* -------------------------------------------------------------------------- */

View File

@ -309,6 +309,33 @@ int Template::erase(Attribute * att)
/* -------------------------------------------------------------------------- */
/* -------------------------------------------------------------------------- */
Attribute * Template::remove(Attribute * att)
{
multimap<string, Attribute *>::iterator i;
pair<
multimap<string, Attribute *>::iterator,
multimap<string, Attribute *>::iterator
> index;
index = attributes.equal_range( att->name() );
for ( i = index.first; i != index.second; i++ )
{
if ( i->second == att )
{
attributes.erase(i);
return att;
}
}
return 0;
}
/* -------------------------------------------------------------------------- */
/* -------------------------------------------------------------------------- */
int Template::get(
const string& name,
vector<const Attribute*>& values) const

222
src/um/Quotas.cc Normal file
View File

@ -0,0 +1,222 @@
/* -------------------------------------------------------------------------- */
/* Copyright 2002-2012, OpenNebula Project Leads (OpenNebula.org) */
/* */
/* Licensed under the Apache License, Version 2.0 (the "License"); you may */
/* not use this file except in compliance with the License. You may obtain */
/* a copy of the License at */
/* */
/* http://www.apache.org/licenses/LICENSE-2.0 */
/* */
/* Unless required by applicable law or agreed to in writing, software */
/* distributed under the License is distributed on an "AS IS" BASIS, */
/* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. */
/* See the License for the specific language governing permissions and */
/* limitations under the License. */
/* -------------------------------------------------------------------------- */
#include "Quotas.h"
#include "Nebula.h"
#include "ObjectXML.h"
int Quotas::set(Template *tmpl, string& error)
{
vector<Attribute *> vquotas;
if ( tmpl->get(datastore_quota.get_quota_name(), vquotas) > 0 )
{
if ( datastore_quota.set(&vquotas, error) != 0 )
{
return -1;
}
vquotas.clear();
}
if ( tmpl->get(network_quota.get_quota_name(), vquotas) > 0 )
{
if ( network_quota.set(&vquotas, error) != 0 )
{
return -1;
}
vquotas.clear();
}
if ( tmpl->get(image_quota.get_quota_name(), vquotas) > 0 )
{
if ( image_quota.set(&vquotas, error) != 0 )
{
return -1;
}
vquotas.clear();
}
if ( tmpl->get(vm_quota.get_quota_name(), vquotas) > 0 )
{
if ( vm_quota.set(&vquotas, error) != 0 )
{
return -1;
}
vquotas.clear();
}
return 0;
}
/* -------------------------------------------------------------------------- */
/* -------------------------------------------------------------------------- */
string& Quotas::to_xml(string& xml) const
{
ostringstream oss;
string ds_quota_xml;
string net_quota_xml;
string vm_quota_xml;
string image_quota_xml;
oss << datastore_quota.to_xml(ds_quota_xml)
<< network_quota.to_xml(net_quota_xml)
<< vm_quota.to_xml(vm_quota_xml)
<< image_quota.to_xml(image_quota_xml);
xml = oss.str();
return xml;
}
/* -------------------------------------------------------------------------- */
/* -------------------------------------------------------------------------- */
int Quotas::from_xml(ObjectXML * object_xml)
{
vector<xmlNodePtr> content;
int rc = 0;
object_xml->get_nodes(ds_xpath, content);
if (!content.empty())
{
rc += datastore_quota.from_xml_node(content[0]);
}
object_xml->free_nodes(content);
content.clear();
object_xml->get_nodes(net_xpath, content);
if (!content.empty())
{
rc += network_quota.from_xml_node(content[0]);
}
object_xml->free_nodes(content);
content.clear();
object_xml->get_nodes(vm_xpath, content);
if (!content.empty())
{
rc += vm_quota.from_xml_node(content[0]);
}
object_xml->free_nodes(content);
content.clear();
object_xml->get_nodes(img_xpath, content);
if (!content.empty())
{
rc += image_quota.from_xml_node(content[0]);
}
object_xml->free_nodes(content);
return rc;
}
/* -------------------------------------------------------------------------- */
/* -------------------------------------------------------------------------- */
void Quotas::vm_del(int uid, int gid, Template * tmpl)
{
Nebula& nd = Nebula::instance();
UserPool * upool = nd.get_upool();
GroupPool * gpool = nd.get_gpool();
User * user;
Group * group;
if ( uid != UserPool::ONEADMIN_ID )
{
user = upool->get(uid, true);
if ( user != 0 )
{
user->quota.vm_del(tmpl);
upool->update(user);
user->unlock();
}
}
if ( gid != GroupPool::ONEADMIN_ID )
{
group = gpool->get(gid, true);
if ( group != 0 )
{
group->quota.vm_del(tmpl);
gpool->update(group);
group->unlock();
}
}
}
/* -------------------------------------------------------------------------- */
/* -------------------------------------------------------------------------- */
void Quotas::ds_del(int uid, int gid, Template * tmpl)
{
Nebula& nd = Nebula::instance();
UserPool * upool = nd.get_upool();
GroupPool * gpool = nd.get_gpool();
User * user;
Group * group;
if ( uid != UserPool::ONEADMIN_ID )
{
user = upool->get(uid, true);
if ( user != 0 )
{
user->quota.ds_del(tmpl);
upool->update(user);
user->unlock();
}
}
if ( gid != GroupPool::ONEADMIN_ID )
{
group = gpool->get(gid, true);
if ( group != 0 )
{
group->quota.ds_del(tmpl);
gpool->update(group);
group->unlock();
}
}
}

View File

@ -28,7 +28,8 @@ source_files=[
'QuotaDatastore.cc',
'QuotaNetwork.cc',
'QuotaVirtualMachine.cc',
'QuotaImage.cc'
'QuotaImage.cc',
'Quotas.cc'
]
# Build library

View File

@ -1109,77 +1109,16 @@ error_common:
/* -------------------------------------------------------------------------- */
/* -------------------------------------------------------------------------- */
// TODO: this method requires the VM to be locked, and then it locks the Image
// to acquire. Check if this can be troublesome
int VirtualMachine::attach_disk(VirtualMachineTemplate * tmpl, string& error_str)
void VirtualMachine::get_disk_info(int& num_disks,
set<string>& used_targets)
{
int num_disks, rc;
vector<Attribute *> disks;
ImagePool * ipool;
VectorAttribute * disk;
VectorAttribute * new_disk;
vector<int> acquired_images;
int new_disk_id;
int image_id;
string dev_prefix;
string target;
string target;
queue<pair <string, VectorAttribute *> > disks_queue;
set<string> used_targets;
ostringstream oss;
Image::ImageType img_type;
Nebula& nd = Nebula::instance();
ipool = nd.get_ipool();
// -------------------------------------------------------------------------
// Get the DISK attribute from the template
// -------------------------------------------------------------------------
num_disks = tmpl->get("DISK", disks);
if ( num_disks != 1 )
{
goto error_no_disk;
}
new_disk = new VectorAttribute( *(dynamic_cast<VectorAttribute * >(disks[0])) );
// -------------------------------------------------------------------------
// See if there is a CONTEXT cdrom, and get the target it is using
// -------------------------------------------------------------------------
num_disks = obj_template->get("CONTEXT", disks);
if ( num_disks > 0 )
{
disk = dynamic_cast<VectorAttribute * >(disks[0]);
if ( disk != 0 )
{
target = disk->vector_value("TARGET");
if ( !target.empty() )
{
used_targets.insert(target);
}
}
}
// -------------------------------------------------------------------------
// Check the used targets
// -------------------------------------------------------------------------
disks.clear();
num_disks = obj_template->get("DISK", disks);
if ( num_disks >= 20 )
{
goto error_max_disks;
}
for(int i=0; i<num_disks; i++)
{
disk = dynamic_cast<VectorAttribute * >(disks[i]);
@ -1197,79 +1136,101 @@ int VirtualMachine::attach_disk(VirtualMachineTemplate * tmpl, string& error_str
}
}
if ( obj_template->get("CONTEXT", disks) > 0 )
{
disk = dynamic_cast<VectorAttribute * >(disks[0]);
if ( disk != 0 )
{
target = disk->vector_value("TARGET");
if ( !target.empty() )
{
used_targets.insert(target);
}
}
}
}
/* -------------------------------------------------------------------------- */
/* -------------------------------------------------------------------------- */
VectorAttribute * VirtualMachine::set_up_attach_disk(
VirtualMachineTemplate * tmpl,
set<string>& used_targets,
int num_disks,
int uid,
int& image_id,
string& error_str)
{
vector<Attribute *> disks;
VectorAttribute * new_disk;
string target;
Nebula& nd = Nebula::instance();
ImagePool * ipool = nd.get_ipool();
ImageManager* imagem = nd.get_imagem();
string dev_prefix;
Image::ImageType img_type;
image_id = -1;
// -------------------------------------------------------------------------
// Get the DISK attribute from the template
// -------------------------------------------------------------------------
if ( tmpl->get("DISK", disks) != 1 )
{
error_str = "The template must contain one DISK attribute";
return 0;
}
new_disk = new VectorAttribute(*(dynamic_cast<VectorAttribute * >(disks[0])));
// -------------------------------------------------------------------------
// Acquire the new disk image
// -------------------------------------------------------------------------
// num_disks +1 because the context is not a DISK, but it takes the
// ds/<vm_id>/disk.num_disks file
new_disk_id = num_disks + 1;
rc = ipool->disk_attribute(new_disk,
new_disk_id,
img_type,
dev_prefix,
uid,
image_id,
error_str);
if ( rc == 0 )
int rc = ipool->disk_attribute(new_disk,
num_disks + 1, //Preserv CONTEXT disk.i file
img_type,
dev_prefix,
uid,
image_id,
error_str);
if ( rc != 0 )
{
acquired_images.push_back(image_id);
return 0;
}
target = new_disk->vector_value("TARGET");
target = new_disk->vector_value("TARGET");
if ( !target.empty() )
if ( !target.empty() )
{
if ( used_targets.insert(target).second == false )
{
if ( used_targets.insert(target).second == false )
{
goto error_duplicated_target;
}
}
else
{
disks_queue.push( make_pair(dev_prefix, new_disk) );
ostringstream oss;
oss << "Target " << target << "is already in use.";
error_str = oss.str();
imagem->release_image(image_id, false);
}
return 0;
}
else
{
goto error_common;
queue<pair <string, VectorAttribute *> > disks_queue;
disks_queue.push(make_pair(dev_prefix, new_disk));
assign_disk_targets(disks_queue, used_targets);
}
assign_disk_targets(disks_queue, used_targets);
// -------------------------------------------------------------------------
// Add the disk to the VM template
// -------------------------------------------------------------------------
new_disk->replace("ATTACH", "YES");
obj_template->set(new_disk);
return 0;
error_no_disk:
error_str = "The template must contain one DISK attribute";
return -1;
error_max_disks:
error_str = "Exceeded the maximum number of disks (20)";
return -1;
error_duplicated_target:
oss << "Two disks have defined the same target " << target;
error_str = oss.str();
error_common:
ImageManager * imagem = nd.get_imagem();
vector<int>::iterator it;
for ( it=acquired_images.begin() ; it < acquired_images.end(); it++ )
{
imagem->release_image(*it, false);
}
return -1;
return new_disk;
}
/* -------------------------------------------------------------------------- */
@ -1281,11 +1242,6 @@ VectorAttribute* VirtualMachine::get_attach_disk()
vector<Attribute *> disks;
VectorAttribute * disk;
ostringstream oss;
// -------------------------------------------------------------------------
// Set DISK attributes & Targets
// -------------------------------------------------------------------------
num_disks = obj_template->get("DISK", disks);
for(int i=0; i<num_disks; i++)
@ -1309,12 +1265,11 @@ VectorAttribute* VirtualMachine::get_attach_disk()
/* -------------------------------------------------------------------------- */
/* -------------------------------------------------------------------------- */
int VirtualMachine::attach_success()
void VirtualMachine::clear_attach_disk()
{
int num_disks;
vector<Attribute *> disks;
VectorAttribute * disk;
bool removed;
num_disks = obj_template->get("DISK", disks);
@ -1330,46 +1285,25 @@ int VirtualMachine::attach_success()
if ( disk->vector_value("ATTACH") == "YES" )
{
disk->remove("ATTACH");
removed = true;
return;
}
}
if ( removed )
{
return 0;
}
return -1;
}
/* -------------------------------------------------------------------------- */
/* -------------------------------------------------------------------------- */
// TODO: this method requires the VM to be locked, and then it locks the Image
// to release. Check if this can be troublesome
int VirtualMachine::attach_failure()
VectorAttribute * VirtualMachine::delete_attach_disk()
{
int num_disks;
vector<Attribute *> disks;
VectorAttribute * disk;
bool found = false;
bool uses_image = false;
int iid;
Nebula& nd = Nebula::instance();
ImageManager * imagem = nd.get_imagem();
int num_disks = obj_template->get("DISK", disks);
num_disks = obj_template->get("DISK", disks);
int i = 0;
while( !found && i<num_disks )
for(int i=0; i<num_disks; i++)
{
disk = dynamic_cast<VectorAttribute * >(disks[i]);
i++;
if ( disk == 0 )
{
continue;
@ -1377,23 +1311,10 @@ int VirtualMachine::attach_failure()
if ( disk->vector_value("ATTACH") == "YES" )
{
uses_image = ( disk->vector_value("IMAGE_ID", iid) != -1 );
obj_template->erase(disk);
found = true;
return static_cast<VectorAttribute * >(obj_template->remove(disk));
}
}
if ( !found )
{
return -1;
}
if ( uses_image )
{
imagem->release_image(iid, false);
}
return 0;
}