mirror of
https://github.com/OpenNebula/one.git
synced 2025-03-11 04:58:16 +03:00
* Fix accounting after onevm resize * Fix crash in VM resize if VM has no history (cherry picked from commit ca934bbde0c6db9cfc4f776d0bcd1f8c7608a3de)
This commit is contained in:
parent
0949062589
commit
e2f2782195
@ -513,6 +513,21 @@ public:
|
||||
*/
|
||||
int backup_cancel(int vid, const RequestAttributes& ra, std::string& error_str);
|
||||
|
||||
/**
|
||||
* Resize cpu and memory
|
||||
*
|
||||
* @param vid the VM id
|
||||
* @param cpu new CPU value
|
||||
* @param vcpu new VCPU value
|
||||
* @param memory new memory value
|
||||
* @param ra information about the API call request
|
||||
* @param error_str Error reason, if any
|
||||
*
|
||||
* @return 0 on success, -1 otherwise
|
||||
*/
|
||||
int resize(int vid, float cpu, int vcpu, long memory,
|
||||
const RequestAttributes& ra, std::string& error_str);
|
||||
|
||||
//--------------------------------------------------------------------------
|
||||
// DM Actions associated with a VM state transition
|
||||
//--------------------------------------------------------------------------
|
||||
|
@ -2852,3 +2852,163 @@ int DispatchManager::backup_cancel(int vid,
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* -------------------------------------------------------------------------- */
|
||||
/* -------------------------------------------------------------------------- */
|
||||
|
||||
static int test_set_capacity(VirtualMachine * vm, float cpu, long mem, int vcpu,
|
||||
string& error)
|
||||
{
|
||||
HostPool * hpool = Nebula::instance().get_hpool();
|
||||
|
||||
int rc;
|
||||
|
||||
if ( vm->get_state() == VirtualMachine::POWEROFF ||
|
||||
(vm->get_state() == VirtualMachine::ACTIVE &&
|
||||
vm->get_lcm_state() == VirtualMachine::RUNNING))
|
||||
{
|
||||
HostShareCapacity sr;
|
||||
|
||||
auto host = hpool->get(vm->get_hid());
|
||||
|
||||
if ( host == nullptr )
|
||||
{
|
||||
error = "Could not update host";
|
||||
return -1;
|
||||
}
|
||||
|
||||
vm->get_capacity(sr);
|
||||
|
||||
host->del_capacity(sr);
|
||||
|
||||
rc = vm->resize(cpu, mem, vcpu, error);
|
||||
|
||||
if ( rc == -1 )
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
|
||||
vm->get_capacity(sr);
|
||||
|
||||
if (!host->test_capacity(sr, error))
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
|
||||
host->add_capacity(sr);
|
||||
|
||||
hpool->update(host.get());
|
||||
}
|
||||
else
|
||||
{
|
||||
rc = vm->resize(cpu, mem, vcpu, error);
|
||||
}
|
||||
|
||||
return rc;
|
||||
}
|
||||
|
||||
int DispatchManager::resize(int vid, float cpu, int vcpu, long memory,
|
||||
const RequestAttributes& ra, string& error_str)
|
||||
{
|
||||
/* ---------------------------------------------------------------------- */
|
||||
/* Check & update VM & host capacity */
|
||||
/* ---------------------------------------------------------------------- */
|
||||
auto vm = vmpool->get(vid);
|
||||
|
||||
if (vm == nullptr)
|
||||
{
|
||||
error_str = "Virtual machine does not exist";
|
||||
|
||||
return -1;
|
||||
}
|
||||
|
||||
int rc;
|
||||
|
||||
switch (vm->get_state())
|
||||
{
|
||||
case VirtualMachine::POWEROFF: //Only check host capacity in POWEROFF
|
||||
case VirtualMachine::INIT:
|
||||
case VirtualMachine::PENDING:
|
||||
case VirtualMachine::HOLD:
|
||||
case VirtualMachine::UNDEPLOYED:
|
||||
case VirtualMachine::CLONING:
|
||||
case VirtualMachine::CLONING_FAILURE:
|
||||
rc = test_set_capacity(vm.get(), cpu, memory, vcpu, error_str);
|
||||
break;
|
||||
|
||||
case VirtualMachine::ACTIVE:
|
||||
{
|
||||
if (vm->get_lcm_state() != VirtualMachine::RUNNING)
|
||||
{
|
||||
rc = -1;
|
||||
error_str = "Cannot resize a VM in state " + vm->state_str();
|
||||
break;
|
||||
}
|
||||
|
||||
if (vm->is_pinned())
|
||||
{
|
||||
rc = -1;
|
||||
error_str = "Cannot resize a pinned VM";
|
||||
break;
|
||||
}
|
||||
|
||||
auto vmm = Nebula::instance().get_vmm();
|
||||
|
||||
if (!vmm->is_live_resize(vm->get_vmm_mad()))
|
||||
{
|
||||
rc = -1;
|
||||
error_str = "Hotplug resize not supported by driver "
|
||||
+ vm->get_vmm_mad();
|
||||
break;
|
||||
}
|
||||
|
||||
long omemory;
|
||||
float ocpu;
|
||||
int ovcpu;
|
||||
|
||||
vm->get_template_attribute("MEMORY", omemory);
|
||||
vm->get_template_attribute("CPU", ocpu);
|
||||
vm->get_template_attribute("VCPU", ovcpu);
|
||||
|
||||
if (ocpu == cpu && omemory == memory && ovcpu == vcpu)
|
||||
{
|
||||
rc = 0;
|
||||
error_str = "Nothing to resize";
|
||||
break;
|
||||
}
|
||||
|
||||
rc = test_set_capacity(vm.get(), cpu, memory, vcpu, error_str);
|
||||
|
||||
if (rc == 0)
|
||||
{
|
||||
vm->set_state(VirtualMachine::HOTPLUG_RESIZE);
|
||||
|
||||
vm->store_resize(ocpu, omemory, ovcpu);
|
||||
|
||||
vm->set_resched(false);
|
||||
|
||||
vmm->trigger_resize(vid);
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
case VirtualMachine::STOPPED:
|
||||
case VirtualMachine::DONE:
|
||||
case VirtualMachine::SUSPENDED:
|
||||
rc = -1;
|
||||
error_str = "Cannot resize a VM in state " + vm->state_str();
|
||||
break;
|
||||
}
|
||||
|
||||
if (rc == 0)
|
||||
{
|
||||
if (vm->hasHistory())
|
||||
{
|
||||
close_cp_history(vmpool, vm.get(), VMActions::RESIZE_ACTION, ra);
|
||||
}
|
||||
|
||||
vmpool->update(vm.get());
|
||||
}
|
||||
|
||||
return rc;
|
||||
}
|
||||
|
@ -2594,7 +2594,7 @@ void LifeCycleManager::trigger_resize_failure(int vid)
|
||||
else
|
||||
{
|
||||
vm->log("LCM", Log::ERROR,
|
||||
"hotplug resize fails, VM in a wrong state");
|
||||
"hotplug resize fails, VM in a wrong state: " + vm->state_str());
|
||||
return;
|
||||
}
|
||||
|
||||
@ -2646,6 +2646,10 @@ void LifeCycleManager::trigger_resize_failure(int vid)
|
||||
|
||||
vm->reset_resize();
|
||||
|
||||
vm->set_vm_info();
|
||||
|
||||
vmpool->update_history(vm.get());
|
||||
|
||||
vmpool->update(vm.get());
|
||||
|
||||
// Revert host capacity
|
||||
|
@ -1971,57 +1971,6 @@ void VirtualMachineDetach::request_execute(xmlrpc_c::paramList const& paramList,
|
||||
/* -------------------------------------------------------------------------- */
|
||||
/* -------------------------------------------------------------------------- */
|
||||
|
||||
static int test_set_capacity(VirtualMachine * vm, float cpu, long mem, int vcpu,
|
||||
string& error)
|
||||
{
|
||||
HostPool * hpool = Nebula::instance().get_hpool();
|
||||
|
||||
int rc;
|
||||
|
||||
if ( vm->get_state() == VirtualMachine::POWEROFF ||
|
||||
(vm->get_state() == VirtualMachine::ACTIVE &&
|
||||
vm->get_lcm_state() == VirtualMachine::RUNNING))
|
||||
{
|
||||
HostShareCapacity sr;
|
||||
|
||||
auto host = hpool->get(vm->get_hid());
|
||||
|
||||
if ( host == nullptr )
|
||||
{
|
||||
error = "Could not update host";
|
||||
return -1;
|
||||
}
|
||||
|
||||
vm->get_capacity(sr);
|
||||
|
||||
host->del_capacity(sr);
|
||||
|
||||
rc = vm->resize(cpu, mem, vcpu, error);
|
||||
|
||||
if ( rc == -1 )
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
|
||||
vm->get_capacity(sr);
|
||||
|
||||
if (!host->test_capacity(sr, error))
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
|
||||
host->add_capacity(sr);
|
||||
|
||||
hpool->update(host.get());
|
||||
}
|
||||
else
|
||||
{
|
||||
rc = vm->resize(cpu, mem, vcpu, error);
|
||||
}
|
||||
|
||||
return rc;
|
||||
}
|
||||
|
||||
void VirtualMachineResize::request_execute(xmlrpc_c::paramList const& paramList,
|
||||
RequestAttributes& att)
|
||||
{
|
||||
@ -2044,9 +1993,7 @@ void VirtualMachineResize::request_execute(xmlrpc_c::paramList const& paramList,
|
||||
// -------------------------------------------------------------------------
|
||||
// Parse template
|
||||
// -------------------------------------------------------------------------
|
||||
int rc = tmpl.parse_str_or_xml(str_tmpl, att.resp_msg);
|
||||
|
||||
if ( rc != 0 )
|
||||
if ( tmpl.parse_str_or_xml(str_tmpl, att.resp_msg) != 0 )
|
||||
{
|
||||
failure_response(INTERNAL, att);
|
||||
return;
|
||||
@ -2181,103 +2128,17 @@ void VirtualMachineResize::request_execute(xmlrpc_c::paramList const& paramList,
|
||||
|
||||
RequestAttributes att_rollback(vm_perms.uid, vm_perms.gid, att);
|
||||
|
||||
/* ---------------------------------------------------------------------- */
|
||||
/* Check & update VM & host capacity */
|
||||
/* ---------------------------------------------------------------------- */
|
||||
auto vm = vmpool->get(id);
|
||||
|
||||
if (vm == nullptr)
|
||||
if ( dm->resize(id, ncpu, nvcpu, nmemory, att, att.resp_msg) == -1 )
|
||||
{
|
||||
att.resp_msg = id;
|
||||
failure_response(NO_EXISTS, att);
|
||||
|
||||
quota_rollback(&deltas, Quotas::VM, att_rollback);
|
||||
return;
|
||||
}
|
||||
|
||||
switch (vm->get_state())
|
||||
{
|
||||
case VirtualMachine::POWEROFF: //Only check host capacity in POWEROFF
|
||||
case VirtualMachine::INIT:
|
||||
case VirtualMachine::PENDING:
|
||||
case VirtualMachine::HOLD:
|
||||
case VirtualMachine::UNDEPLOYED:
|
||||
case VirtualMachine::CLONING:
|
||||
case VirtualMachine::CLONING_FAILURE:
|
||||
rc = test_set_capacity(vm.get(), ncpu, nmemory, nvcpu, att.resp_msg);
|
||||
break;
|
||||
|
||||
case VirtualMachine::ACTIVE:
|
||||
{
|
||||
if (vm->get_lcm_state() != VirtualMachine::RUNNING)
|
||||
{
|
||||
rc = -1;
|
||||
att.resp_msg = "Cannot resize a VM in state " + vm->state_str();
|
||||
break;
|
||||
}
|
||||
|
||||
if (vm->is_pinned())
|
||||
{
|
||||
rc = -1;
|
||||
att.resp_msg = "Cannot resize a pinned VM";
|
||||
break;
|
||||
}
|
||||
|
||||
auto vmm = Nebula::instance().get_vmm();
|
||||
|
||||
if (!vmm->is_live_resize(vm->get_vmm_mad()))
|
||||
{
|
||||
rc = -1;
|
||||
att.resp_msg = "Hotplug resize not supported by driver "
|
||||
+ vm->get_vmm_mad();
|
||||
break;
|
||||
}
|
||||
|
||||
if (ocpu == ncpu && omemory == nmemory && ovcpu == nvcpu)
|
||||
{
|
||||
rc = 0;
|
||||
att.resp_msg = "Nothing to resize";
|
||||
break;
|
||||
}
|
||||
|
||||
rc = test_set_capacity(vm.get(), ncpu, nmemory, nvcpu, att.resp_msg);
|
||||
|
||||
if (rc == 0)
|
||||
{
|
||||
vm->set_state(VirtualMachine::HOTPLUG_RESIZE);
|
||||
|
||||
vm->store_resize(ocpu, omemory, ovcpu);
|
||||
|
||||
vm->set_resched(false);
|
||||
|
||||
vmm->trigger_resize(id);
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
case VirtualMachine::STOPPED:
|
||||
case VirtualMachine::DONE:
|
||||
case VirtualMachine::SUSPENDED:
|
||||
rc = -1;
|
||||
att.resp_msg = "Cannot resize a VM in state " + vm->state_str();
|
||||
break;
|
||||
}
|
||||
|
||||
if ( rc == -1 )
|
||||
{
|
||||
vm.reset();
|
||||
|
||||
quota_rollback(&deltas, Quotas::VM, att_rollback);
|
||||
|
||||
failure_response(ACTION, att);
|
||||
}
|
||||
else
|
||||
{
|
||||
vmpool->update(vm.get());
|
||||
|
||||
success_response(id, att);
|
||||
return;
|
||||
}
|
||||
|
||||
success_response(id, att);
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user