mirror of
https://github.com/OpenNebula/one.git
synced 2025-03-08 20:58:17 +03:00
feature #1233: Added quotas.Refactor Attach methods
This commit is contained in:
parent
554321c73b
commit
1dbeaa1719
@ -232,6 +232,7 @@ public:
|
|||||||
* Set the re-scheduling flag for the VM (must be in RUNNING state)
|
* Set the re-scheduling flag for the VM (must be in RUNNING state)
|
||||||
* @param vid VirtualMachine identification
|
* @param vid VirtualMachine identification
|
||||||
* @param do_resched set or unset the flag
|
* @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
|
* @return 0 on success, -1 if the VM does not exits or -2 if the VM is
|
||||||
* in a wrong a state
|
* in a wrong a state
|
||||||
*/
|
*/
|
||||||
@ -240,19 +241,14 @@ public:
|
|||||||
bool do_resched);
|
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
|
* @return 0 on success, -1 otherwise
|
||||||
* 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
|
|
||||||
*/
|
*/
|
||||||
int attach(
|
int attach(int vid, VirtualMachineTemplate * tmpl, string & error_str);
|
||||||
VirtualMachine * vm,
|
|
||||||
VirtualMachineTemplate * tmpl,
|
|
||||||
string & error_str);
|
|
||||||
|
|
||||||
private:
|
private:
|
||||||
/**
|
/**
|
||||||
|
135
include/Quotas.h
135
include/Quotas.h
@ -22,6 +22,8 @@
|
|||||||
#include "QuotaVirtualMachine.h"
|
#include "QuotaVirtualMachine.h"
|
||||||
#include "QuotaImage.h"
|
#include "QuotaImage.h"
|
||||||
|
|
||||||
|
class ObjectXML;
|
||||||
|
|
||||||
class Quotas
|
class Quotas
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
@ -44,52 +46,7 @@ public:
|
|||||||
*
|
*
|
||||||
* @return 0 on success, -1 otherwise
|
* @return 0 on success, -1 otherwise
|
||||||
*/
|
*/
|
||||||
int set(Template *tmpl, string& error)
|
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;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Check Datastore quotas, it updates usage counters if quotas are not
|
* Check Datastore quotas, it updates usage counters if quotas are not
|
||||||
@ -159,76 +116,32 @@ public:
|
|||||||
* @param xml the string to store the XML
|
* @param xml the string to store the XML
|
||||||
* @return the same xml string to use it in << compounds
|
* @return the same xml string to use it in << compounds
|
||||||
*/
|
*/
|
||||||
string& to_xml(string& xml) const
|
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;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Builds quota object from an ObjectXML
|
* Builds quota object from an ObjectXML
|
||||||
* @param object_xml pointer to the ObjectXML
|
* @param object_xml pointer to the ObjectXML
|
||||||
* @return 0 if success
|
* @return 0 if success
|
||||||
*/
|
*/
|
||||||
int from_xml(ObjectXML * object_xml)
|
int from_xml(ObjectXML * object_xml);
|
||||||
{
|
|
||||||
vector<xmlNodePtr> content;
|
|
||||||
int rc = 0;
|
|
||||||
|
|
||||||
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())
|
/**
|
||||||
{
|
* Delete Datastore related usage from quota counters.
|
||||||
rc += datastore_quota.from_xml_node(content[0]);
|
* for the given user and group
|
||||||
}
|
* @param uid of the user
|
||||||
|
* @param gid of the group
|
||||||
object_xml->free_nodes(content);
|
* @param tmpl template for the image, with usage
|
||||||
content.clear();
|
*/
|
||||||
|
static void ds_del(int uid, int gid, Template * tmpl);
|
||||||
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;
|
|
||||||
}
|
|
||||||
|
|
||||||
private:
|
private:
|
||||||
//--------------------------------------------------------------------------
|
//--------------------------------------------------------------------------
|
||||||
@ -238,17 +151,17 @@ private:
|
|||||||
/**
|
/**
|
||||||
* Datastore Quotas
|
* Datastore Quotas
|
||||||
*/
|
*/
|
||||||
QuotaDatastore datastore_quota;
|
QuotaDatastore datastore_quota;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Network Quotas
|
* Network Quotas
|
||||||
*/
|
*/
|
||||||
QuotaNetwork network_quota;
|
QuotaNetwork network_quota;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Image Quotas
|
* Image Quotas
|
||||||
*/
|
*/
|
||||||
QuotaImage image_quota;
|
QuotaImage image_quota;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Virtual Machine Quotas
|
* Virtual Machine Quotas
|
||||||
|
@ -49,11 +49,12 @@ protected:
|
|||||||
RequestAttributes& att) = 0;
|
RequestAttributes& att) = 0;
|
||||||
|
|
||||||
bool vm_authorization(int id,
|
bool vm_authorization(int id,
|
||||||
ImageTemplate * tmpl,
|
ImageTemplate * tmpl,
|
||||||
RequestAttributes& att,
|
VirtualMachineTemplate* vtmpl,
|
||||||
PoolObjectAuth * host_perms,
|
RequestAttributes& att,
|
||||||
PoolObjectAuth * ds_perm,
|
PoolObjectAuth * host_perms,
|
||||||
AuthRequest::Operation op);
|
PoolObjectAuth * ds_perm,
|
||||||
|
AuthRequest::Operation op);
|
||||||
|
|
||||||
int get_host_information(int hid, string& name, string& vmm, string& vnm,
|
int get_host_information(int hid, string& name, string& vmm, string& vnm,
|
||||||
RequestAttributes& att, PoolObjectAuth& host_perms);
|
RequestAttributes& att, PoolObjectAuth& host_perms);
|
||||||
|
@ -169,6 +169,15 @@ public:
|
|||||||
const string& name,
|
const string& name,
|
||||||
vector<Attribute *>& values);
|
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.
|
* Removes an attribute from the template, and frees the attributes.
|
||||||
* @param name of the attribute
|
* @param name of the attribute
|
||||||
|
@ -24,6 +24,7 @@
|
|||||||
#include "NebulaLog.h"
|
#include "NebulaLog.h"
|
||||||
|
|
||||||
#include <time.h>
|
#include <time.h>
|
||||||
|
#include <set>
|
||||||
#include <sstream>
|
#include <sstream>
|
||||||
|
|
||||||
using namespace std;
|
using namespace std;
|
||||||
@ -744,17 +745,31 @@ public:
|
|||||||
// ------------------------------------------------------------------------
|
// ------------------------------------------------------------------------
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Attaches a new disk. It will acquire the Image used, if any, and add the
|
* Collects information about VM DISKS
|
||||||
* disk to the VM template. The VM must be updated in the DB afterwards.
|
* @param num_disks of the VM
|
||||||
*
|
* @param used_targets by the DISKS of the VM
|
||||||
* @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
|
|
||||||
*/
|
*/
|
||||||
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
|
* Returns the disk that is waiting for an attachment action
|
||||||
*
|
*
|
||||||
@ -764,18 +779,27 @@ public:
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* Cleans the ATTACH = YES attribute from the disks
|
* 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
|
* Deletes the DISK that was in the process of being attached
|
||||||
* the image, if any
|
|
||||||
*
|
*
|
||||||
* @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:
|
private:
|
||||||
|
|
||||||
|
@ -685,9 +685,6 @@ int DispatchManager::finalize(
|
|||||||
VirtualMachine * vm;
|
VirtualMachine * vm;
|
||||||
ostringstream oss;
|
ostringstream oss;
|
||||||
Template * tmpl;
|
Template * tmpl;
|
||||||
|
|
||||||
User * user;
|
|
||||||
Group * group;
|
|
||||||
|
|
||||||
int uid;
|
int uid;
|
||||||
int gid;
|
int gid;
|
||||||
@ -709,8 +706,6 @@ int DispatchManager::finalize(
|
|||||||
Nebula& nd = Nebula::instance();
|
Nebula& nd = Nebula::instance();
|
||||||
TransferManager * tm = nd.get_tm();
|
TransferManager * tm = nd.get_tm();
|
||||||
LifeCycleManager * lcm = nd.get_lcm();
|
LifeCycleManager * lcm = nd.get_lcm();
|
||||||
UserPool * upool = nd.get_upool();
|
|
||||||
GroupPool * gpool = nd.get_gpool();
|
|
||||||
|
|
||||||
switch (state)
|
switch (state)
|
||||||
{
|
{
|
||||||
@ -739,34 +734,7 @@ int DispatchManager::finalize(
|
|||||||
|
|
||||||
vm->unlock();
|
vm->unlock();
|
||||||
|
|
||||||
if ( uid != UserPool::ONEADMIN_ID )
|
Quotas::vm_del(uid, gid, tmpl);
|
||||||
{
|
|
||||||
|
|
||||||
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();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
delete tmpl;
|
delete tmpl;
|
||||||
break;
|
break;
|
||||||
@ -845,59 +813,96 @@ int DispatchManager::resubmit(int vid)
|
|||||||
/* -------------------------------------------------------------------------- */
|
/* -------------------------------------------------------------------------- */
|
||||||
/* -------------------------------------------------------------------------- */
|
/* -------------------------------------------------------------------------- */
|
||||||
|
|
||||||
int DispatchManager::attach(
|
|
||||||
VirtualMachine * vm,
|
int DispatchManager::attach(int vid,
|
||||||
VirtualMachineTemplate * tmpl,
|
VirtualMachineTemplate * tmpl,
|
||||||
string & error_str)
|
string & error_str)
|
||||||
{
|
{
|
||||||
ostringstream oss;
|
ostringstream oss;
|
||||||
int rc;
|
|
||||||
int vid = vm->get_oid();
|
|
||||||
|
|
||||||
Nebula& nd = Nebula::instance();
|
int num_disks;
|
||||||
VirtualMachineManager * vmm = nd.get_vmm();
|
int uid;
|
||||||
|
int image_id;
|
||||||
|
|
||||||
oss << "Attaching a new disk to VM " << vid;
|
set<string> used_targets;
|
||||||
NebulaLog::log("DiM",Log::DEBUG,oss);
|
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 ||
|
if ( vm->get_state() != VirtualMachine::ACTIVE ||
|
||||||
vm->get_lcm_state() != VirtualMachine::RUNNING )
|
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 )
|
vm->unlock();
|
||||||
{
|
return -1;
|
||||||
goto error;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
vm->get_disk_info(num_disks, used_targets);
|
||||||
|
|
||||||
vm->set_state(VirtualMachine::HOTPLUG);
|
vm->set_state(VirtualMachine::HOTPLUG);
|
||||||
|
|
||||||
|
vm->set_resched(false);
|
||||||
|
|
||||||
|
uid = vm->get_uid();
|
||||||
|
|
||||||
vmpool->update(vm);
|
vmpool->update(vm);
|
||||||
|
|
||||||
vm->unlock();
|
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;
|
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;
|
|
||||||
}
|
}
|
||||||
|
@ -108,13 +108,6 @@ void DispatchManager::done_action(int vid)
|
|||||||
VirtualMachine::LcmState lcm_state;
|
VirtualMachine::LcmState lcm_state;
|
||||||
VirtualMachine::VmState dm_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);
|
vm = vmpool->get(vid,true);
|
||||||
|
|
||||||
if ( vm == 0 )
|
if ( vm == 0 )
|
||||||
@ -150,35 +143,7 @@ void DispatchManager::done_action(int vid)
|
|||||||
|
|
||||||
vm->unlock();
|
vm->unlock();
|
||||||
|
|
||||||
/* ---------------- Update Group & User quota counters -------------- */
|
Quotas::vm_del(uid, gid, tmpl);
|
||||||
|
|
||||||
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();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
delete tmpl;
|
delete tmpl;
|
||||||
}
|
}
|
||||||
|
@ -274,13 +274,7 @@ int ImageManager::delete_image(int iid, const string& ds_data)
|
|||||||
|
|
||||||
int uid;
|
int uid;
|
||||||
int gid;
|
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);
|
img = ipool->get(iid,true);
|
||||||
|
|
||||||
if ( img == 0 )
|
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("DATASTORE", ds_id);
|
||||||
img_usage.add("SIZE", size);
|
img_usage.add("SIZE", size);
|
||||||
|
|
||||||
if ( uid != UserPool::ONEADMIN_ID )
|
Quotas::ds_del(uid, gid, &img_usage);
|
||||||
{
|
|
||||||
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();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
@ -846,7 +846,7 @@ void LifeCycleManager::attach_success_action(int vid)
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
vm->attach_success();
|
vm->clear_attach_disk();
|
||||||
|
|
||||||
vm->set_state(VirtualMachine::RUNNING);
|
vm->set_state(VirtualMachine::RUNNING);
|
||||||
|
|
||||||
@ -860,7 +860,11 @@ void LifeCycleManager::attach_success_action(int vid)
|
|||||||
|
|
||||||
void LifeCycleManager::attach_failure_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);
|
vm = vmpool->get(vid,true);
|
||||||
|
|
||||||
@ -869,7 +873,9 @@ void LifeCycleManager::attach_failure_action(int vid)
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
vm->attach_failure();
|
disk = vm->delete_attach_disk();
|
||||||
|
uid = vm->get_uid();
|
||||||
|
gid = vm->get_gid();
|
||||||
|
|
||||||
vm->set_state(VirtualMachine::RUNNING);
|
vm->set_state(VirtualMachine::RUNNING);
|
||||||
|
|
||||||
@ -877,7 +883,14 @@ void LifeCycleManager::attach_failure_action(int vid)
|
|||||||
|
|
||||||
vm->unlock();
|
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);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/* -------------------------------------------------------------------------- */
|
/* -------------------------------------------------------------------------- */
|
||||||
|
@ -22,12 +22,13 @@
|
|||||||
/* -------------------------------------------------------------------------- */
|
/* -------------------------------------------------------------------------- */
|
||||||
|
|
||||||
bool RequestManagerVirtualMachine::vm_authorization(
|
bool RequestManagerVirtualMachine::vm_authorization(
|
||||||
int oid,
|
int oid,
|
||||||
ImageTemplate * tmpl,
|
ImageTemplate * tmpl,
|
||||||
RequestAttributes& att,
|
VirtualMachineTemplate* vtmpl,
|
||||||
PoolObjectAuth * host_perm,
|
RequestAttributes& att,
|
||||||
PoolObjectAuth * ds_perm,
|
PoolObjectAuth * host_perm,
|
||||||
AuthRequest::Operation op)
|
PoolObjectAuth * ds_perm,
|
||||||
|
AuthRequest::Operation op)
|
||||||
{
|
{
|
||||||
PoolObjectSQL * object;
|
PoolObjectSQL * object;
|
||||||
PoolObjectAuth vm_perms;
|
PoolObjectAuth vm_perms;
|
||||||
@ -69,6 +70,11 @@ bool RequestManagerVirtualMachine::vm_authorization(
|
|||||||
ar.add_create_auth(PoolObjectSQL::IMAGE, tmpl->to_xml(t_xml));
|
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 )
|
if ( ds_perm != 0 )
|
||||||
{
|
{
|
||||||
ar.add_auth(AuthRequest::USE, *ds_perm);
|
ar.add_auth(AuthRequest::USE, *ds_perm);
|
||||||
@ -196,7 +202,7 @@ void VirtualMachineAction::request_execute(xmlrpc_c::paramList const& paramList,
|
|||||||
op = AuthRequest::ADMIN;
|
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;
|
return;
|
||||||
}
|
}
|
||||||
@ -313,7 +319,7 @@ void VirtualMachineDeploy::request_execute(xmlrpc_c::paramList const& paramList,
|
|||||||
return;
|
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 )
|
if ( auth == false )
|
||||||
{
|
{
|
||||||
@ -375,7 +381,7 @@ void VirtualMachineMigrate::request_execute(xmlrpc_c::paramList const& paramList
|
|||||||
return;
|
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 )
|
if ( auth == false )
|
||||||
{
|
{
|
||||||
@ -546,7 +552,7 @@ void VirtualMachineSaveDisk::request_execute(xmlrpc_c::paramList const& paramLis
|
|||||||
// Authorize the operation & check quotas
|
// 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;
|
delete itemplate;
|
||||||
return;
|
return;
|
||||||
@ -598,7 +604,7 @@ void VirtualMachineMonitoring::request_execute(
|
|||||||
|
|
||||||
ostringstream oss;
|
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 )
|
if ( auth == false )
|
||||||
{
|
{
|
||||||
@ -624,59 +630,66 @@ void VirtualMachineMonitoring::request_execute(
|
|||||||
void VirtualMachineAttach::request_execute(xmlrpc_c::paramList const& paramList,
|
void VirtualMachineAttach::request_execute(xmlrpc_c::paramList const& paramList,
|
||||||
RequestAttributes& att)
|
RequestAttributes& att)
|
||||||
{
|
{
|
||||||
Nebula& nd = Nebula::instance();
|
Nebula& nd = Nebula::instance();
|
||||||
DispatchManager * dm = nd.get_dm();
|
DispatchManager * dm = nd.get_dm();
|
||||||
|
|
||||||
VirtualMachine * vm;
|
VirtualMachine * vm;
|
||||||
VirtualMachineTemplate * tmpl;
|
VirtualMachineTemplate * tmpl = new VirtualMachineTemplate();
|
||||||
PoolObjectAuth host_perms;
|
PoolObjectAuth host_perms;
|
||||||
|
|
||||||
int rc;
|
int rc;
|
||||||
string error_str;
|
string error_str;
|
||||||
|
|
||||||
int id = xmlrpc_c::value_int(paramList.getInt(1));
|
int id = xmlrpc_c::value_int(paramList.getInt(1));
|
||||||
string str_tmpl = xmlrpc_c::value_string(paramList.getString(2));
|
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 )
|
if ( rc != 0 )
|
||||||
{
|
{
|
||||||
failure_response(INTERNAL, "", att); // TODO: error message
|
failure_response(INTERNAL, error_str, att);
|
||||||
delete tmpl;
|
delete tmpl;
|
||||||
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO: auth & quotas
|
// -------------------------------------------------------------------------
|
||||||
|
// Authorize the operation & check quotas
|
||||||
// TODO: set vm state HOTPLUG & vm->set_resched(false); // Cancel re-scheduling actions
|
// -------------------------------------------------------------------------
|
||||||
|
|
||||||
vm = get_vm(id, att);
|
if ( vm_authorization(id, 0, tmpl, att, 0, 0, auth_op) == false )
|
||||||
|
|
||||||
if ( vm == 0 )
|
|
||||||
{
|
{
|
||||||
failure_response(NO_EXISTS,
|
|
||||||
get_error(object_name(auth_object),id),
|
|
||||||
att);
|
|
||||||
delete tmpl;
|
delete tmpl;
|
||||||
|
|
||||||
return;
|
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 )
|
if ( rc != 0 )
|
||||||
{
|
{
|
||||||
|
quota_rollback(tmpl, att);
|
||||||
|
|
||||||
failure_response(ACTION,
|
failure_response(ACTION,
|
||||||
request_error(error_str, ""),
|
request_error(error_str, ""),
|
||||||
att);
|
att);
|
||||||
|
}
|
||||||
return;
|
else
|
||||||
|
{
|
||||||
|
success_response(id, att);
|
||||||
}
|
}
|
||||||
|
|
||||||
success_response(id, att);
|
delete tmpl;
|
||||||
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* -------------------------------------------------------------------------- */
|
/* -------------------------------------------------------------------------- */
|
||||||
|
@ -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(
|
int Template::get(
|
||||||
const string& name,
|
const string& name,
|
||||||
vector<const Attribute*>& values) const
|
vector<const Attribute*>& values) const
|
||||||
|
222
src/um/Quotas.cc
Normal file
222
src/um/Quotas.cc
Normal 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();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -28,7 +28,8 @@ source_files=[
|
|||||||
'QuotaDatastore.cc',
|
'QuotaDatastore.cc',
|
||||||
'QuotaNetwork.cc',
|
'QuotaNetwork.cc',
|
||||||
'QuotaVirtualMachine.cc',
|
'QuotaVirtualMachine.cc',
|
||||||
'QuotaImage.cc'
|
'QuotaImage.cc',
|
||||||
|
'Quotas.cc'
|
||||||
]
|
]
|
||||||
|
|
||||||
# Build library
|
# Build library
|
||||||
|
@ -1109,77 +1109,16 @@ error_common:
|
|||||||
/* -------------------------------------------------------------------------- */
|
/* -------------------------------------------------------------------------- */
|
||||||
/* -------------------------------------------------------------------------- */
|
/* -------------------------------------------------------------------------- */
|
||||||
|
|
||||||
// TODO: this method requires the VM to be locked, and then it locks the Image
|
void VirtualMachine::get_disk_info(int& num_disks,
|
||||||
// to acquire. Check if this can be troublesome
|
set<string>& used_targets)
|
||||||
|
|
||||||
int VirtualMachine::attach_disk(VirtualMachineTemplate * tmpl, string& error_str)
|
|
||||||
{
|
{
|
||||||
int num_disks, rc;
|
|
||||||
vector<Attribute *> disks;
|
vector<Attribute *> disks;
|
||||||
ImagePool * ipool;
|
|
||||||
VectorAttribute * disk;
|
VectorAttribute * disk;
|
||||||
VectorAttribute * new_disk;
|
|
||||||
vector<int> acquired_images;
|
|
||||||
|
|
||||||
int new_disk_id;
|
string target;
|
||||||
int image_id;
|
|
||||||
string dev_prefix;
|
|
||||||
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);
|
num_disks = obj_template->get("DISK", disks);
|
||||||
|
|
||||||
if ( num_disks >= 20 )
|
|
||||||
{
|
|
||||||
goto error_max_disks;
|
|
||||||
}
|
|
||||||
|
|
||||||
for(int i=0; i<num_disks; i++)
|
for(int i=0; i<num_disks; i++)
|
||||||
{
|
{
|
||||||
disk = dynamic_cast<VectorAttribute * >(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
|
// Acquire the new disk image
|
||||||
// -------------------------------------------------------------------------
|
// -------------------------------------------------------------------------
|
||||||
|
|
||||||
// num_disks +1 because the context is not a DISK, but it takes the
|
int rc = ipool->disk_attribute(new_disk,
|
||||||
// ds/<vm_id>/disk.num_disks file
|
num_disks + 1, //Preserv CONTEXT disk.i file
|
||||||
new_disk_id = num_disks + 1;
|
img_type,
|
||||||
|
dev_prefix,
|
||||||
rc = ipool->disk_attribute(new_disk,
|
uid,
|
||||||
new_disk_id,
|
image_id,
|
||||||
img_type,
|
error_str);
|
||||||
dev_prefix,
|
if ( rc != 0 )
|
||||||
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 )
|
ostringstream oss;
|
||||||
{
|
|
||||||
goto error_duplicated_target;
|
oss << "Target " << target << "is already in use.";
|
||||||
}
|
error_str = oss.str();
|
||||||
}
|
|
||||||
else
|
imagem->release_image(image_id, false);
|
||||||
{
|
|
||||||
disks_queue.push( make_pair(dev_prefix, new_disk) );
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
}
|
}
|
||||||
else
|
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);
|
return new_disk;
|
||||||
|
|
||||||
// -------------------------------------------------------------------------
|
|
||||||
// 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;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* -------------------------------------------------------------------------- */
|
/* -------------------------------------------------------------------------- */
|
||||||
@ -1281,11 +1242,6 @@ VectorAttribute* VirtualMachine::get_attach_disk()
|
|||||||
vector<Attribute *> disks;
|
vector<Attribute *> disks;
|
||||||
VectorAttribute * disk;
|
VectorAttribute * disk;
|
||||||
|
|
||||||
ostringstream oss;
|
|
||||||
|
|
||||||
// -------------------------------------------------------------------------
|
|
||||||
// Set DISK attributes & Targets
|
|
||||||
// -------------------------------------------------------------------------
|
|
||||||
num_disks = obj_template->get("DISK", disks);
|
num_disks = obj_template->get("DISK", disks);
|
||||||
|
|
||||||
for(int i=0; i<num_disks; i++)
|
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;
|
int num_disks;
|
||||||
vector<Attribute *> disks;
|
vector<Attribute *> disks;
|
||||||
VectorAttribute * disk;
|
VectorAttribute * disk;
|
||||||
bool removed;
|
|
||||||
|
|
||||||
num_disks = obj_template->get("DISK", disks);
|
num_disks = obj_template->get("DISK", disks);
|
||||||
|
|
||||||
@ -1330,46 +1285,25 @@ int VirtualMachine::attach_success()
|
|||||||
if ( disk->vector_value("ATTACH") == "YES" )
|
if ( disk->vector_value("ATTACH") == "YES" )
|
||||||
{
|
{
|
||||||
disk->remove("ATTACH");
|
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
|
VectorAttribute * VirtualMachine::delete_attach_disk()
|
||||||
// to release. Check if this can be troublesome
|
|
||||||
|
|
||||||
int VirtualMachine::attach_failure()
|
|
||||||
{
|
{
|
||||||
int num_disks;
|
|
||||||
vector<Attribute *> disks;
|
vector<Attribute *> disks;
|
||||||
VectorAttribute * disk;
|
VectorAttribute * disk;
|
||||||
bool found = false;
|
|
||||||
bool uses_image = false;
|
|
||||||
int iid;
|
|
||||||
|
|
||||||
Nebula& nd = Nebula::instance();
|
int num_disks = obj_template->get("DISK", disks);
|
||||||
ImageManager * imagem = nd.get_imagem();
|
|
||||||
|
|
||||||
num_disks = obj_template->get("DISK", disks);
|
for(int i=0; i<num_disks; i++)
|
||||||
|
|
||||||
int i = 0;
|
|
||||||
|
|
||||||
while( !found && i<num_disks )
|
|
||||||
{
|
{
|
||||||
disk = dynamic_cast<VectorAttribute * >(disks[i]);
|
disk = dynamic_cast<VectorAttribute * >(disks[i]);
|
||||||
|
|
||||||
i++;
|
|
||||||
|
|
||||||
if ( disk == 0 )
|
if ( disk == 0 )
|
||||||
{
|
{
|
||||||
continue;
|
continue;
|
||||||
@ -1377,23 +1311,10 @@ int VirtualMachine::attach_failure()
|
|||||||
|
|
||||||
if ( disk->vector_value("ATTACH") == "YES" )
|
if ( disk->vector_value("ATTACH") == "YES" )
|
||||||
{
|
{
|
||||||
uses_image = ( disk->vector_value("IMAGE_ID", iid) != -1 );
|
return static_cast<VectorAttribute * >(obj_template->remove(disk));
|
||||||
|
|
||||||
obj_template->erase(disk);
|
|
||||||
found = true;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if ( !found )
|
|
||||||
{
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
if ( uses_image )
|
|
||||||
{
|
|
||||||
imagem->release_image(iid, false);
|
|
||||||
}
|
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user