diff --git a/include/LifeCycleManager.h b/include/LifeCycleManager.h index 0ca499fce0..d05eca4b6a 100644 --- a/include/LifeCycleManager.h +++ b/include/LifeCycleManager.h @@ -213,8 +213,6 @@ private: void attach_success_action(int vid); - void delete_attach_disk(int vid, bool release_save_as); - void attach_failure_action(int vid); void detach_success_action(int vid); diff --git a/include/VirtualMachinePool.h b/include/VirtualMachinePool.h index 2228c77169..8c7a569e8a 100644 --- a/include/VirtualMachinePool.h +++ b/include/VirtualMachinePool.h @@ -339,6 +339,23 @@ public: int end_year, string &error_str); + /** + * Deletes the DISK that was in the process of being attached. Releases + * Images and updates usage quotas + * + * @param vid VM id + * @param release_save_as true to release non-persistent images + * in the detach event + */ + void delete_attach_disk(int vid, bool release_save_as); + + /** + * Deletes the NIC that was in the process of being attached + * + * @param vid VM id + */ + void delete_attach_nic(int vid); + private: /** * Factory method to produce VM objects diff --git a/src/dm/DispatchManagerActions.cc b/src/dm/DispatchManagerActions.cc index 7741c0e888..7bf883cb62 100644 --- a/src/dm/DispatchManagerActions.cc +++ b/src/dm/DispatchManagerActions.cc @@ -1474,8 +1474,9 @@ int DispatchManager::attach_nic( return -1; } - if ( vm->get_state() != VirtualMachine::ACTIVE || - vm->get_lcm_state() != VirtualMachine::RUNNING ) + if (( vm->get_state() != VirtualMachine::ACTIVE || + vm->get_lcm_state() != VirtualMachine::RUNNING ) && + vm->get_state() != VirtualMachine::POWEROFF ) { oss << "Could not add a new NIC to VM " << vid << ", wrong state."; error_str = oss.str(); @@ -1498,7 +1499,11 @@ int DispatchManager::attach_nic( vm->get_security_groups(vm_sgs); - vm->set_state(VirtualMachine::HOTPLUG_NIC); + if (vm->get_state() == VirtualMachine::ACTIVE && + vm->get_lcm_state() == VirtualMachine::RUNNING ) + { + vm->set_state(VirtualMachine::HOTPLUG_NIC); + } vm->set_resched(false); @@ -1552,7 +1557,10 @@ int DispatchManager::attach_nic( delete *it; } - vm->set_state(VirtualMachine::RUNNING); + if (vm->get_lcm_state() == VirtualMachine::HOTPLUG_NIC) + { + vm->set_state(VirtualMachine::RUNNING); + } vmpool->update(vm); @@ -1567,12 +1575,21 @@ int DispatchManager::attach_nic( vm->set_attach_nic(nic, sg_rules); } + if (vm->get_lcm_state() == VirtualMachine::HOTPLUG_NIC) + { + vmm->trigger(VirtualMachineManager::ATTACH_NIC,vid); + } + else + { + vm->log("DiM", Log::INFO, "VM NIC Successfully attached."); + + vm->clear_attach_nic(); + } + vmpool->update(vm); vm->unlock(); - vmm->trigger(VirtualMachineManager::ATTACH_NIC,vid); - return 0; } @@ -1600,8 +1617,9 @@ int DispatchManager::detach_nic( return -1; } - if ( vm->get_state() != VirtualMachine::ACTIVE || - vm->get_lcm_state() != VirtualMachine::RUNNING ) + if (( vm->get_state() != VirtualMachine::ACTIVE || + vm->get_lcm_state() != VirtualMachine::RUNNING ) && + vm->get_state() != VirtualMachine::POWEROFF ) { oss << "Could not detach NIC from VM " << vid << ", wrong state."; error_str = oss.str(); @@ -1624,15 +1642,27 @@ int DispatchManager::detach_nic( return -1; } - vm->set_state(VirtualMachine::HOTPLUG_NIC); + if (vm->get_state() == VirtualMachine::ACTIVE && + vm->get_lcm_state() == VirtualMachine::RUNNING ) + { + vm->set_state(VirtualMachine::HOTPLUG_NIC); - vm->set_resched(false); + vm->set_resched(false); - vmpool->update(vm); + vmpool->update(vm); - vm->unlock(); + vm->unlock(); - vmm->trigger(VirtualMachineManager::DETACH_NIC,vid); + vmm->trigger(VirtualMachineManager::DETACH_NIC,vid); + } + else + { + vm->unlock(); + + vmpool->delete_attach_nic(vid); + + vm->log("DiM", Log::INFO, "VM NIC Successfully detached."); + } return 0; } diff --git a/src/lcm/LifeCycleStates.cc b/src/lcm/LifeCycleStates.cc index 8f9f782beb..39d35886cc 100644 --- a/src/lcm/LifeCycleStates.cc +++ b/src/lcm/LifeCycleStates.cc @@ -1451,73 +1451,6 @@ void LifeCycleManager::attach_success_action(int vid) /* -------------------------------------------------------------------------- */ /* -------------------------------------------------------------------------- */ -void LifeCycleManager::delete_attach_disk(int vid, bool release_save_as) -{ - VirtualMachine * vm; - VectorAttribute * disk; - - int uid; - int gid; - int oid; - - vm = vmpool->get(vid,true); - - if ( vm == 0 ) - { - return; - } - - disk = vm->delete_attach_disk(); - uid = vm->get_uid(); - gid = vm->get_gid(); - oid = vm->get_oid(); - - vmpool->update(vm); - - vm->unlock(); - - if ( disk != 0 ) - { - Nebula& nd = Nebula::instance(); - ImageManager* imagem = nd.get_imagem(); - - Template tmpl; - int image_id; - - tmpl.set(disk); - - if ( disk->vector_value("IMAGE_ID", image_id) == 0 ) - { - // Disk using an Image - Quotas::quota_del(Quotas::IMAGE, uid, gid, &tmpl); - - imagem->release_image(oid, image_id, false); - - // Release non-persistent images in the detach event - if (release_save_as) - { - int save_as_id; - - if ( disk->vector_value("SAVE_AS", save_as_id) == 0 ) - { - imagem->release_image(oid, save_as_id, false); - } - } - } - else // Volatile disk - { - // It is an update of the volatile counter without - // shutting destroying a VM - tmpl.add("VMS", 0); - - Quotas::quota_del(Quotas::VM, uid, gid, &tmpl); - } - } -} - -/* -------------------------------------------------------------------------- */ -/* -------------------------------------------------------------------------- */ - void LifeCycleManager::attach_failure_action(int vid) { VirtualMachine * vm; @@ -1534,7 +1467,7 @@ void LifeCycleManager::attach_failure_action(int vid) { vm->unlock(); - delete_attach_disk(vid, false); + vmpool->delete_attach_disk(vid, false); vm = vmpool->get(vid,true); @@ -1584,7 +1517,7 @@ void LifeCycleManager::detach_success_action(int vid) { vm->unlock(); - delete_attach_disk(vid, true); + vmpool->delete_attach_disk(vid, true); vm = vmpool->get(vid,true); @@ -1853,11 +1786,6 @@ void LifeCycleManager::attach_nic_success_action(int vid) void LifeCycleManager::attach_nic_failure_action(int vid) { VirtualMachine * vm; - VectorAttribute * nic; - - int uid; - int gid; - int oid; vm = vmpool->get(vid,true); @@ -1868,27 +1796,22 @@ void LifeCycleManager::attach_nic_failure_action(int vid) if ( vm->get_lcm_state() == VirtualMachine::HOTPLUG_NIC ) { - nic = vm->delete_attach_nic(); - uid = vm->get_uid(); - gid = vm->get_gid(); - oid = vm->get_oid(); + vm->unlock(); + + vmpool->delete_attach_nic(vid); + + vm = vmpool->get(vid,true); + + if ( vm == 0 ) + { + return; + } vm->set_state(VirtualMachine::RUNNING); vmpool->update(vm); vm->unlock(); - - if ( nic != 0 ) - { - Template tmpl; - - tmpl.set(nic); - - Quotas::quota_del(Quotas::NETWORK, uid, gid, &tmpl); - - VirtualMachine::release_network_leases(nic, oid); - } } else { diff --git a/src/vm/VirtualMachinePool.cc b/src/vm/VirtualMachinePool.cc index 7a8e1341d2..fd57083ce8 100644 --- a/src/vm/VirtualMachinePool.cc +++ b/src/vm/VirtualMachinePool.cc @@ -1035,3 +1035,107 @@ int VirtualMachinePool::calculate_showback( /* -------------------------------------------------------------------------- */ /* -------------------------------------------------------------------------- */ + +void VirtualMachinePool::delete_attach_disk(int vid, bool release_save_as) +{ + VirtualMachine * vm; + VectorAttribute * disk; + + int uid; + int gid; + int oid; + + vm = get(vid,true); + + if ( vm == 0 ) + { + return; + } + + disk = vm->delete_attach_disk(); + uid = vm->get_uid(); + gid = vm->get_gid(); + oid = vm->get_oid(); + + update(vm); + + vm->unlock(); + + if ( disk != 0 ) + { + Nebula& nd = Nebula::instance(); + ImageManager* imagem = nd.get_imagem(); + + Template tmpl; + int image_id; + + tmpl.set(disk); + + if ( disk->vector_value("IMAGE_ID", image_id) == 0 ) + { + // Disk using an Image + Quotas::quota_del(Quotas::IMAGE, uid, gid, &tmpl); + + imagem->release_image(oid, image_id, false); + + // Release non-persistent images in the detach event + if (release_save_as) + { + int save_as_id; + + if ( disk->vector_value("SAVE_AS", save_as_id) == 0 ) + { + imagem->release_image(oid, save_as_id, false); + } + } + } + else // Volatile disk + { + // It is an update of the volatile counter without + // shutting destroying a VM + tmpl.add("VMS", 0); + + Quotas::quota_del(Quotas::VM, uid, gid, &tmpl); + } + } +} + +/* -------------------------------------------------------------------------- */ +/* -------------------------------------------------------------------------- */ + +void VirtualMachinePool::delete_attach_nic(int vid) +{ + VirtualMachine * vm; + VectorAttribute * nic; + + int uid; + int gid; + int oid; + + vm = get(vid,true); + + if ( vm == 0 ) + { + return; + } + + nic = vm->delete_attach_nic(); + uid = vm->get_uid(); + gid = vm->get_gid(); + oid = vm->get_oid(); + + update(vm); + + vm->unlock(); + + if ( nic != 0 ) + { + Template tmpl; + + tmpl.set(nic); + + Quotas::quota_del(Quotas::NETWORK, uid, gid, &tmpl); + + VirtualMachine::release_network_leases(nic, oid); + } +}