mirror of
https://github.com/OpenNebula/one.git
synced 2025-01-03 01:17:41 +03:00
F #4393: More work on resize
This commit is contained in:
parent
178489ef11
commit
c1c3d0479d
@ -347,6 +347,7 @@ public:
|
||||
int id,
|
||||
int nic_id,
|
||||
string& error_str);
|
||||
|
||||
/**
|
||||
* Starts the snapshot create action
|
||||
*
|
||||
@ -441,6 +442,21 @@ public:
|
||||
int snap_id,
|
||||
string& error_str);
|
||||
|
||||
/**
|
||||
* Starts the disk resize create action
|
||||
*
|
||||
* @param vid VirtualMachine identification
|
||||
* @param did DISK identification
|
||||
* @param size new size for the disk
|
||||
* @param error_str Error reason, if any
|
||||
*
|
||||
* @return 0 on success, -1 otherwise
|
||||
*/
|
||||
int disk_resize(
|
||||
int vid,
|
||||
int did,
|
||||
long long new_size,
|
||||
string& error_str);
|
||||
|
||||
private:
|
||||
/**
|
||||
|
@ -483,4 +483,26 @@ public:
|
||||
RequestAttributes& att);
|
||||
};
|
||||
|
||||
/* -------------------------------------------------------------------------- */
|
||||
/* -------------------------------------------------------------------------- */
|
||||
|
||||
class VirtualMachineDiskResize : public RequestManagerVirtualMachine
|
||||
{
|
||||
public:
|
||||
VirtualMachineDiskResize():
|
||||
RequestManagerVirtualMachine("VirtualMachineDiskResize",
|
||||
"Resizes a disk from a virtual machine",
|
||||
"A:siis"){
|
||||
Nebula& nd = Nebula::instance();
|
||||
ipool = nd.get_ipool();
|
||||
};
|
||||
|
||||
~VirtualMachineDiskResize(){};
|
||||
|
||||
void request_execute(xmlrpc_c::paramList const& _paramList,
|
||||
RequestAttributes& att);
|
||||
private:
|
||||
ImagePool* ipool;
|
||||
};
|
||||
|
||||
#endif
|
||||
|
@ -412,6 +412,14 @@ public:
|
||||
*/
|
||||
virtual bool has_restricted();
|
||||
|
||||
/**
|
||||
* @return true if template is empty
|
||||
*/
|
||||
bool empty()
|
||||
{
|
||||
return attributes.empty();
|
||||
}
|
||||
|
||||
protected:
|
||||
/**
|
||||
* The template attributes
|
||||
|
@ -232,6 +232,32 @@ public:
|
||||
*/
|
||||
void delete_snapshot(int snap_id, Template **ds_quota, Template **vm_quota);
|
||||
|
||||
/* ---------------------------------------------------------------------- */
|
||||
/* Disk space usage functions */
|
||||
/* ---------------------------------------------------------------------- */
|
||||
|
||||
/**
|
||||
* @return the space required by this disk in the system datastore
|
||||
*/
|
||||
long long system_ds_size();
|
||||
|
||||
/**
|
||||
* Calculate the quotas for a resize operation on the disk
|
||||
* @param new_size of disk
|
||||
* @param dsdeltas increment in datastore usage
|
||||
* @param vmdelta increment in system datastore usage
|
||||
*/
|
||||
void resize_quotas(long long new_size, Template& dsdelta, Template& vmdelta);
|
||||
|
||||
/**
|
||||
* Compute the storage needed by the disk in the system and/or image
|
||||
* datastore
|
||||
* @param ds_id of the datastore
|
||||
* @param img_sz size in image datastore needed
|
||||
* @param sys_sz size in system datastore needed
|
||||
*/
|
||||
void datastore_sizes(int& ds_id, long long& img_sz, long long& sys_sz);
|
||||
|
||||
private:
|
||||
|
||||
Snapshots * snapshots;
|
||||
|
@ -2045,3 +2045,127 @@ int DispatchManager::disk_snapshot_delete(
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* -------------------------------------------------------------------------- */
|
||||
/* -------------------------------------------------------------------------- */
|
||||
|
||||
int DispatchManager::disk_resize(
|
||||
int vid,
|
||||
int did,
|
||||
long long new_size,
|
||||
string& error_str)
|
||||
{
|
||||
ostringstream oss;
|
||||
time_t the_time;
|
||||
|
||||
VirtualMachine * vm = vmpool->get(vid, true);
|
||||
|
||||
if ( vm == 0 )
|
||||
{
|
||||
oss << "Could not resize disk for VM " << vid << ", VM does not exist" ;
|
||||
error_str = oss.str();
|
||||
|
||||
NebulaLog::log("DiM", Log::ERROR, error_str);
|
||||
return -1;
|
||||
}
|
||||
|
||||
VirtualMachine::VmState state = vm->get_state();
|
||||
VirtualMachine::LcmState lstate = vm->get_lcm_state();
|
||||
|
||||
if ((state !=VirtualMachine::POWEROFF || lstate !=VirtualMachine::LCM_INIT)&&
|
||||
(state !=VirtualMachine::STOPPED || lstate !=VirtualMachine::LCM_INIT)&&
|
||||
(state !=VirtualMachine::UNDEPLOYED || lstate !=VirtualMachine::LCM_INIT)&&
|
||||
(state !=VirtualMachine::ACTIVE || lstate !=VirtualMachine::RUNNING))
|
||||
{
|
||||
oss << "Could not resize disk for VM " << vid << ", wrong state "
|
||||
<< vm->state_str() << ".";
|
||||
error_str = oss.str();
|
||||
|
||||
NebulaLog::log("DiM", Log::ERROR, error_str);
|
||||
|
||||
vm->unlock();
|
||||
|
||||
return -1;
|
||||
}
|
||||
|
||||
// Set the VM info in the history before the disk is resized
|
||||
vm->set_vm_info();
|
||||
|
||||
int rc = vm->set_up_resize_disk(did, new_size, error_str);
|
||||
|
||||
if (rc == -1)
|
||||
{
|
||||
vm->unlock();
|
||||
return -1;
|
||||
}
|
||||
/*
|
||||
switch(state)
|
||||
{
|
||||
case VirtualMachine::POWEROFF:
|
||||
vm->set_state(VirtualMachine::ACTIVE);
|
||||
vm->set_state(VirtualMachine::DISK_RESIZE_POWEROFF);
|
||||
break;
|
||||
|
||||
case VirtualMachine::STOPPED:
|
||||
vm->set_state(VirtualMachine::ACTIVE);
|
||||
vm->set_state(VirtualMachine::DISK_RESIZE_STOPPED);
|
||||
break;
|
||||
|
||||
case VirtualMachine::UNDEPLOYED:
|
||||
vm->set_state(VirtualMachine::ACTIVE);
|
||||
vm->set_state(VirtualMachine::DISK_RESIZE_UNDEPLOYED);
|
||||
break;
|
||||
|
||||
case VirtualMachine::ACTIVE:
|
||||
vm->set_state(VirtualMachine::ACTIVE);
|
||||
vm->set_state(VirtualMachine::DISK_RESIZE);
|
||||
break;
|
||||
|
||||
default: break;
|
||||
}
|
||||
|
||||
vmpool->update(vm);
|
||||
|
||||
vm->unlock();
|
||||
|
||||
switch(state)
|
||||
{
|
||||
case VirtualMachine::POWEROFF:
|
||||
case VirtualMachine::SUSPENDED:
|
||||
tm->trigger(TransferManager::SNAPSHOT_CREATE,vid);
|
||||
break;
|
||||
|
||||
case VirtualMachine::ACTIVE:
|
||||
the_time = time(0);
|
||||
|
||||
// Close current history record
|
||||
|
||||
vm->set_running_etime(the_time);
|
||||
|
||||
vm->set_etime(the_time);
|
||||
|
||||
vm->set_action(History::DISK_SNAPSHOT_CREATE_ACTION);
|
||||
vm->set_reason(History::USER);
|
||||
|
||||
vmpool->update_history(vm);
|
||||
|
||||
// Open a new history record
|
||||
|
||||
vm->cp_history();
|
||||
|
||||
vm->set_stime(the_time);
|
||||
|
||||
vm->set_running_stime(the_time);
|
||||
|
||||
vmpool->update_history(vm);
|
||||
|
||||
vmm->trigger(VirtualMachineManager::DISK_SNAPSHOT_CREATE, vid);
|
||||
break;
|
||||
|
||||
default: break;
|
||||
}
|
||||
*/
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* -------------------------------------------------------------------------- */
|
||||
/* -------------------------------------------------------------------------- */
|
||||
|
@ -1994,7 +1994,7 @@ void LifeCycleManager::disk_snapshot_success(int vid)
|
||||
}
|
||||
|
||||
// Update image if it is persistent and ln mode does not clone it
|
||||
if ( img_id != -1 && is_persistent && has_snaps && target != "SYSTEM" )
|
||||
if ( img_id != -1 && is_persistent && has_snaps && target == "NONE" )
|
||||
{
|
||||
imagem->set_image_snapshots(img_id, snaps);
|
||||
}
|
||||
|
@ -2888,3 +2888,188 @@ void VirtualMachineUpdateConf::request_execute(
|
||||
vm->unlock();
|
||||
}
|
||||
|
||||
/* -------------------------------------------------------------------------- */
|
||||
/* -------------------------------------------------------------------------- */
|
||||
|
||||
void VirtualMachineDiskResize::request_execute(
|
||||
xmlrpc_c::paramList const& paramList,
|
||||
RequestAttributes& att)
|
||||
{
|
||||
Nebula& nd = Nebula::instance();
|
||||
DispatchManager * dm = nd.get_dm();
|
||||
|
||||
VirtualMachine * vm;
|
||||
|
||||
Template ds_deltas;
|
||||
Template vm_deltas;
|
||||
|
||||
PoolObjectAuth vm_perms;
|
||||
|
||||
int id = xmlrpc_c::value_int(paramList.getInt(1));
|
||||
int did = xmlrpc_c::value_int(paramList.getInt(2));
|
||||
string size_s = xmlrpc_c::value_string(paramList.getString(3));
|
||||
|
||||
long long size , current_size;
|
||||
|
||||
// ------------------------------------------------------------------------
|
||||
// Check request consistency (VM & disk exists, size, and no snapshots)
|
||||
// ------------------------------------------------------------------------
|
||||
istringstream iss(size_s);
|
||||
|
||||
iss >> size;
|
||||
|
||||
if (iss.fail() || !iss.eof())
|
||||
{
|
||||
att.resp_msg = "Disk SIZE is not a valid integer";
|
||||
failure_response(ACTION, att);
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
if ((vm = get_vm(id, att)) == 0)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
VirtualMachineDisk * disk =vm->get_disk(did);
|
||||
|
||||
if (disk == 0)
|
||||
{
|
||||
att.resp_msg = "VM disk does not exist";
|
||||
failure_response(ACTION, att);
|
||||
|
||||
vm->unlock();
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
disk->vector_value("SIZE", current_size);
|
||||
|
||||
if ( size <= current_size )
|
||||
{
|
||||
att.resp_msg = "New disk size has to be greater than current one";
|
||||
failure_response(ACTION, att);
|
||||
|
||||
vm->unlock();
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
if ( disk->has_snapshots() )
|
||||
{
|
||||
att.resp_msg = "Cannot resize a disk with snapshots";
|
||||
failure_response(ACTION, att);
|
||||
|
||||
vm->unlock();
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
/* ------------- Get information about the disk and image --------------- */
|
||||
bool is_persistent = disk->is_persistent();
|
||||
|
||||
disk->resize_quotas(size, ds_deltas, vm_deltas);
|
||||
|
||||
int img_id = -1;
|
||||
disk->vector_value("IMAGE_ID", img_id);
|
||||
|
||||
vm->get_permissions(vm_perms);
|
||||
|
||||
vm->unlock();
|
||||
|
||||
/* ---------------------------------------------------------------------- */
|
||||
/* Authorize the request for VM and IMAGE for persistent disks */
|
||||
/* ---------------------------------------------------------------------- */
|
||||
RequestAttributes ds_att_quota;
|
||||
RequestAttributes vm_att_quota;
|
||||
|
||||
if ( is_persistent )
|
||||
{
|
||||
PoolObjectAuth img_perms;
|
||||
|
||||
if ( img_id != -1 )
|
||||
{
|
||||
Image* img = ipool->get(img_id, true);
|
||||
|
||||
if (img == 0)
|
||||
{
|
||||
att.resp_obj = PoolObjectSQL::IMAGE;
|
||||
att.resp_id = img_id;
|
||||
failure_response(NO_EXISTS, att);
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
img->get_permissions(img_perms);
|
||||
|
||||
img->unlock();
|
||||
}
|
||||
|
||||
if (vm_authorization(id, 0, 0, att, 0, 0, &img_perms, auth_op) == false)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
ds_att_quota = RequestAttributes(img_perms.uid, img_perms.gid, att);
|
||||
}
|
||||
else
|
||||
{
|
||||
if ( vm_authorization(id, 0, 0, att, 0, 0, 0, auth_op) == false )
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
ds_att_quota = RequestAttributes(vm_perms.uid, vm_perms.gid, att);
|
||||
}
|
||||
|
||||
/* ---------------------------------------------------------------------- */
|
||||
/* Check quotas for the new size in image/system datastoress */
|
||||
/* ---------------------------------------------------------------------- */
|
||||
|
||||
if ( !ds_deltas.empty() )
|
||||
{
|
||||
if (!quota_authorization(&ds_deltas, Quotas::DATASTORE, ds_att_quota))
|
||||
{
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
if ( !vm_deltas.empty() )
|
||||
{
|
||||
if (!quota_resize_authorization(id, &vm_deltas, vm_att_quota))
|
||||
{
|
||||
if (!ds_deltas.empty())
|
||||
{
|
||||
quota_rollback(&ds_deltas, Quotas::DATASTORE, ds_att_quota);
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
// ------------------------------------------------------------------------
|
||||
// Do the snapshot
|
||||
// ------------------------------------------------------------------------
|
||||
int rc = dm->disk_resize(id, did, size, att.resp_msg);
|
||||
|
||||
if ( rc != 0 )
|
||||
{
|
||||
if ( !ds_deltas.empty() )
|
||||
{
|
||||
quota_rollback(&ds_deltas, Quotas::DATASTORE, ds_att_quota);
|
||||
}
|
||||
|
||||
if ( !vm_deltas.empty() )
|
||||
{
|
||||
quota_rollback(&vm_deltas, Quotas::VM, vm_att_quota);
|
||||
}
|
||||
|
||||
failure_response(ACTION, att);
|
||||
}
|
||||
else
|
||||
{
|
||||
success_response(did, att);
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
|
@ -316,6 +316,112 @@ void VirtualMachineDisk::delete_snapshot(int snap_id, Template **ds_quotas,
|
||||
}
|
||||
}
|
||||
|
||||
/* -------------------------------------------------------------------------- */
|
||||
/* -------------------------------------------------------------------------- */
|
||||
|
||||
long long VirtualMachineDisk::system_ds_size()
|
||||
{
|
||||
long long disk_sz, snapshot_sz = 0;
|
||||
|
||||
if ( vector_value("SIZE", disk_sz) != 0 )
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
//Volatile disks don't have snapshots
|
||||
if (vector_value("DISK_SNAPSHOT_TOTAL_SIZE", snapshot_sz) == 0)
|
||||
{
|
||||
disk_sz += snapshot_sz;
|
||||
}
|
||||
|
||||
if ( is_volatile() || get_tm_target() == "SYSTEM" )
|
||||
{
|
||||
return disk_sz;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* -------------------------------------------------------------------------- */
|
||||
/* -------------------------------------------------------------------------- */
|
||||
|
||||
void VirtualMachineDisk::resize_quotas(long long new_size, Template& ds_deltas,
|
||||
Template& vm_deltas)
|
||||
{
|
||||
long long current_size, delta_size;
|
||||
|
||||
if ( vector_value("SIZE", current_size) != 0 )
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
delta_size = new_size - current_size;
|
||||
|
||||
bool is_system = get_tm_target() == "SYSTEM";
|
||||
string ds_id = vector_value("DATASTORE_ID");
|
||||
|
||||
if ( !is_volatile() && ( is_persistent() || !is_system ) )
|
||||
{
|
||||
ds_deltas.add("DATASTORE", ds_id);
|
||||
ds_deltas.add("SIZE", delta_size);
|
||||
ds_deltas.add("IMAGES", 0);
|
||||
}
|
||||
|
||||
if ( is_volatile() || is_system )
|
||||
{
|
||||
VectorAttribute * delta_disk = new VectorAttribute("DISK");
|
||||
delta_disk->replace("TYPE", "FS");
|
||||
delta_disk->replace("SIZE", delta_size);
|
||||
|
||||
vm_deltas.add("VMS", 0);
|
||||
vm_deltas.set(delta_disk);
|
||||
}
|
||||
}
|
||||
|
||||
/* -------------------------------------------------------------------------- */
|
||||
/* -------------------------------------------------------------------------- */
|
||||
|
||||
void VirtualMachineDisk::datastore_sizes(int& ds_id, long long& image_sz,
|
||||
long long& system_sz)
|
||||
{
|
||||
long long tmp_size, snapshot_size;
|
||||
|
||||
image_sz = 0;
|
||||
system_sz = 0;
|
||||
ds_id = -1;
|
||||
|
||||
if ( vector_value("SIZE", tmp_size) != 0 )
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
if ( vector_value("DISK_SNAPSHOT_TOTAL_SIZE", snapshot_size) == 0 )
|
||||
{
|
||||
tmp_size += snapshot_size;
|
||||
}
|
||||
|
||||
if ( is_volatile() )
|
||||
{
|
||||
system_sz = tmp_size;
|
||||
return;
|
||||
}
|
||||
else
|
||||
{
|
||||
string target = get_tm_target();
|
||||
|
||||
if ( target == "SYSTEM" )
|
||||
{
|
||||
system_sz = tmp_size;
|
||||
}
|
||||
else if ( target == "SELF" )
|
||||
{
|
||||
vector_value("DATASTORE_ID", ds_id);
|
||||
|
||||
image_sz = tmp_size;
|
||||
}// else if ( target == "NONE" )
|
||||
}
|
||||
}
|
||||
|
||||
/* -------------------------------------------------------------------------- */
|
||||
/* -------------------------------------------------------------------------- */
|
||||
/* -------------------------------------------------------------------------- */
|
||||
@ -341,26 +447,7 @@ long long VirtualMachineDisks::system_ds_size()
|
||||
|
||||
for ( disk_iterator disk = begin() ; disk != end() ; ++disk )
|
||||
{
|
||||
long long tmp_size;
|
||||
|
||||
if ( (*disk)->vector_value("SIZE", tmp_size) != 0 )
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
if ( (*disk)->is_volatile() )
|
||||
{
|
||||
size += tmp_size;
|
||||
}
|
||||
else if ( (*disk)->get_tm_target() == "SYSTEM" )
|
||||
{
|
||||
size += tmp_size;
|
||||
|
||||
if ((*disk)->vector_value("DISK_SNAPSHOT_TOTAL_SIZE",tmp_size) == 0)
|
||||
{
|
||||
size += tmp_size;
|
||||
}
|
||||
}
|
||||
size += (*disk)->system_ds_size();
|
||||
}
|
||||
|
||||
return size;
|
||||
@ -373,6 +460,33 @@ long long VirtualMachineDisks::system_ds_size(Template * ds_tmpl)
|
||||
return disks.system_ds_size();
|
||||
}
|
||||
|
||||
/* -------------------------------------------------------------------------- */
|
||||
/* -------------------------------------------------------------------------- */
|
||||
/*
|
||||
void VirtualMachineDisks::image_ds_size(bool resize_snapshot, long long system,
|
||||
std::map<int, long long>& ds_size) const
|
||||
{
|
||||
int ds_id;
|
||||
long long system_sz, image_sz;
|
||||
|
||||
for ( disk_iterator disk = begin() ; disk != end() ; ++disk )
|
||||
{
|
||||
(*disk)->ds_size(resize_snapshot, ds_id, image_sz, system_sz);
|
||||
|
||||
system += system_sz;
|
||||
|
||||
if ( ds_id != -1 && image_sz > 0 )
|
||||
{
|
||||
if (ds_size.count(ds_id) == 0)
|
||||
{
|
||||
ds_size[ds_id] = 0;
|
||||
}
|
||||
|
||||
ds_size[ds_id] += image_sz;
|
||||
}
|
||||
}
|
||||
}
|
||||
*/
|
||||
/* -------------------------------------------------------------------------- */
|
||||
/* -------------------------------------------------------------------------- */
|
||||
|
||||
@ -418,14 +532,6 @@ bool VirtualMachineDisks::volatile_info(int ds_id)
|
||||
/* -------------------------------------------------------------------------- */
|
||||
/* -------------------------------------------------------------------------- */
|
||||
|
||||
void VirtualMachineDisks::image_ds_size(std::map<int, long long>& ds_size) const
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
/* -------------------------------------------------------------------------- */
|
||||
/* -------------------------------------------------------------------------- */
|
||||
|
||||
void VirtualMachineDisks::get_image_ids(set<int>& ids, int uid)
|
||||
{
|
||||
int id;
|
||||
|
Loading…
Reference in New Issue
Block a user