diff --git a/include/VirtualMachine.h b/include/VirtualMachine.h index 6ec148b6f1..60dcdaf597 100644 --- a/include/VirtualMachine.h +++ b/include/VirtualMachine.h @@ -66,31 +66,33 @@ public: */ enum LcmState { - LCM_INIT = 0, - PROLOG = 1, - BOOT = 2, - RUNNING = 3, - MIGRATE = 4, - SAVE_STOP = 5, - SAVE_SUSPEND = 6, - SAVE_MIGRATE = 7, - PROLOG_MIGRATE = 8, - PROLOG_RESUME = 9, - EPILOG_STOP = 10, - EPILOG = 11, - SHUTDOWN = 12, - CANCEL = 13, - FAILURE = 14, - CLEANUP_RESUBMIT = 15, - UNKNOWN = 16, - HOTPLUG = 17, - SHUTDOWN_POWEROFF = 18, - BOOT_UNKNOWN = 19, - BOOT_POWEROFF = 20, - BOOT_SUSPENDED = 21, - BOOT_STOPPED = 22, - CLEANUP_DELETE = 23, - HOTPLUG_SAVEAS = 24 + LCM_INIT = 0, + PROLOG = 1, + BOOT = 2, + RUNNING = 3, + MIGRATE = 4, + SAVE_STOP = 5, + SAVE_SUSPEND = 6, + SAVE_MIGRATE = 7, + PROLOG_MIGRATE = 8, + PROLOG_RESUME = 9, + EPILOG_STOP = 10, + EPILOG = 11, + SHUTDOWN = 12, + CANCEL = 13, + FAILURE = 14, + CLEANUP_RESUBMIT = 15, + UNKNOWN = 16, + HOTPLUG = 17, + SHUTDOWN_POWEROFF = 18, + BOOT_UNKNOWN = 19, + BOOT_POWEROFF = 20, + BOOT_SUSPENDED = 21, + BOOT_STOPPED = 22, + CLEANUP_DELETE = 23, + HOTPLUG_SAVEAS = 24, + HOTPLUG_SAVEAS_POWEROFF = 25, + HOTPLUG_SAVEAS_SUSPENDED = 26 }; // ------------------------------------------------------------------------- diff --git a/src/image/ImageManagerDriver.cc b/src/image/ImageManagerDriver.cc index fa09841d88..ff054a6dc4 100644 --- a/src/image/ImageManagerDriver.cc +++ b/src/image/ImageManagerDriver.cc @@ -326,6 +326,10 @@ static void mkfs_action(istringstream& is, string info; int rc; + istringstream iss; + int vm_oid; + int disk_oid; + VirtualMachine * vm; ostringstream oss; @@ -357,9 +361,35 @@ static void mkfs_action(istringstream& is, return; } + is_saving = image->isSaving(); + is_hot = image->isHot(); + + if ( is_saving ) + { + image->get_template_attribute("SAVED_DISK_ID", disk_id); + image->get_template_attribute("SAVED_VM_ID", vm_id); + + iss.str(vm_id); + iss >> vm_oid; + + iss.clear(); + + iss.str(disk_id); + iss >> disk_oid; + } + if ( result == "FAILURE" ) { - goto error_img; + if ( is_hot ) + { + LifeCycleManager * lcm = nd.get_lcm(); + lcm->trigger(LifeCycleManager::HOTPLUG_SAVEAS_FAILURE, vm_oid); + goto error_img_hot; + } + else + { + goto error_img; + } } if ( is.good() ) @@ -372,32 +402,20 @@ static void mkfs_action(istringstream& is, goto error_img; } - is_saving = image->isSaving(); - - is_hot = image->isHot(); - image->set_source(source); - if (is_saving) + if ( !is_saving && !is_hot ) { - image->get_template_attribute("SAVED_DISK_ID", disk_id); - image->get_template_attribute("SAVED_VM_ID", vm_id); + image->set_state(Image::READY); } - else - { - if ( !is_hot ) - { - image->set_state(Image::READY); - } - NebulaLog::log("ImM", Log::INFO, "Image created and ready to use"); - } + NebulaLog::log("ImM", Log::INFO, "Image created and ready to use"); ipool->update(image); image->unlock(); - if ( ! is_saving ) + if ( !is_saving ) { return; } @@ -411,34 +429,12 @@ static void mkfs_action(istringstream& is, if ( is_hot ) { - istringstream iss; - int vm_oid; - int disk_oid; - - /* change state */ - - iss.str(vm_id); - iss >> vm_oid; - - iss.clear(); - - iss.str(disk_id); - iss >> disk_oid; - - vm->set_state(VirtualMachine::HOTPLUG_SAVEAS); vm->set_hotplug_saveas(disk_oid, id); - vm->set_resched(false); - - vmpool->update(vm); - - vm->log("LCM", Log::INFO, "New VM state is HOTPLUG_SAVEAS"); - - /* call tm */ - - TransferManager * tm = nd.get_tm(); + TransferManager * tm = nd.get_tm(); vm->unlock(); + tm->saveas_hot_transfer_command(vm_oid, disk_oid, source); } else @@ -458,6 +454,7 @@ static void mkfs_action(istringstream& is, return; +error_img_hot: error_img: oss << "Error creating datablock"; goto error; diff --git a/src/lcm/LifeCycleStates.cc b/src/lcm/LifeCycleStates.cc index 36169d6d80..8c324399d6 100644 --- a/src/lcm/LifeCycleStates.cc +++ b/src/lcm/LifeCycleStates.cc @@ -1226,6 +1226,28 @@ void LifeCycleManager::hotplug_saveas_success_action(int vid) vmpool->update(vm); } + else if (vm->get_lcm_state() == VirtualMachine::HOTPLUG_SAVEAS_POWEROFF) + { + image_id = vm->get_hotplug_saveas_image_id(); + + vm->clear_hotplug_saveas(); + + vm->set_state(VirtualMachine::POWEROFF); + vm->set_state(VirtualMachine::LCM_INIT); + + vmpool->update(vm); + } + else if (vm->get_lcm_state() == VirtualMachine::HOTPLUG_SAVEAS_SUSPENDED) + { + image_id = vm->get_hotplug_saveas_image_id(); + + vm->clear_hotplug_saveas(); + + vm->set_state(VirtualMachine::SUSPENDED); + vm->set_state(VirtualMachine::LCM_INIT); + + vmpool->update(vm); + } else { vm->log("LCM",Log::ERROR,"hotplug_saveas_success_action," @@ -1234,7 +1256,6 @@ void LifeCycleManager::hotplug_saveas_success_action(int vid) vm->unlock(); - ostringstream oss; image = ipool->get(image_id, true); @@ -1282,6 +1303,28 @@ void LifeCycleManager::hotplug_saveas_failure_action(int vid) vmpool->update(vm); } + else if (vm->get_lcm_state() == VirtualMachine::HOTPLUG_SAVEAS_POWEROFF) + { + image_id = vm->get_hotplug_saveas_image_id(); + + vm->clear_hotplug_saveas(); + + vm->set_state(VirtualMachine::POWEROFF); + vm->set_state(VirtualMachine::LCM_INIT); + + vmpool->update(vm); + } + else if (vm->get_lcm_state() == VirtualMachine::HOTPLUG_SAVEAS_SUSPENDED) + { + image_id = vm->get_hotplug_saveas_image_id(); + + vm->clear_hotplug_saveas(); + + vm->set_state(VirtualMachine::SUSPENDED); + vm->set_state(VirtualMachine::LCM_INIT); + + vmpool->update(vm); + } else { vm->log("LCM",Log::ERROR,"hotplug_saveas_success_action," @@ -1290,7 +1333,6 @@ void LifeCycleManager::hotplug_saveas_failure_action(int vid) vm->unlock(); - ostringstream oss; image = ipool->get(image_id, true); diff --git a/src/rm/RequestManagerVirtualMachine.cc b/src/rm/RequestManagerVirtualMachine.cc index 180a9e5395..43bd98b9d7 100644 --- a/src/rm/RequestManagerVirtualMachine.cc +++ b/src/rm/RequestManagerVirtualMachine.cc @@ -697,6 +697,7 @@ void VirtualMachineSaveDisk::request_execute(xmlrpc_c::paramList const& paramLis is_hot = xmlrpc_c::value_boolean(paramList.getBoolean(5)); } + VirtualMachinePool * vmpool = static_cast(pool); VirtualMachine * vm; int iid; int iid_orig; @@ -726,8 +727,22 @@ void VirtualMachineSaveDisk::request_execute(xmlrpc_c::paramList const& paramLis return; } + if (!( (vm->get_state() == VirtualMachine::POWEROFF) || + (vm->get_state() == VirtualMachine::SUSPENDED) || + (vm->get_state() == VirtualMachine::ACTIVE && + vm->get_lcm_state() == VirtualMachine::RUNNING))) + { + failure_response(ACTION, + request_error("Wrong state to perform action",""), + att); + + vm->unlock(); + return; + } + iid_orig = vm->get_image_from_disk(disk_id, error_str); + // TODO: remove this update? pool->update(vm); vm->unlock(); @@ -809,6 +824,55 @@ void VirtualMachineSaveDisk::request_execute(xmlrpc_c::paramList const& paramLis return; } + // ------------------------------------------------------------------------- + // Change to one of the HOTPLUG_SAVEAS states if it's a hot saveas + // ------------------------------------------------------------------------- + + if ( is_hot ) + { + vm = vmpool->get(id,true); + + if ( vm == 0 ) + { + failure_response(NO_EXISTS, + get_error(object_name(PoolObjectSQL::VM), id), + att); + return; + } + + if ( vm->get_state() == VirtualMachine::ACTIVE && + vm->get_lcm_state() == VirtualMachine::RUNNING) + { + vm->set_state(VirtualMachine::HOTPLUG_SAVEAS); + } + else if (vm->get_state() == VirtualMachine::POWEROFF) + { + vm->set_state(VirtualMachine::ACTIVE); + vm->set_state(VirtualMachine::HOTPLUG_SAVEAS_POWEROFF); + } + else if (vm->get_state() == VirtualMachine::SUSPENDED) + { + vm->set_state(VirtualMachine::ACTIVE); + vm->set_state(VirtualMachine::HOTPLUG_SAVEAS_SUSPENDED); + } + else + { + failure_response(ACTION, + request_error("Wrong state to perform action",""), + att); + + vm->unlock(); + return; + } + + vm->log("RM", Log::INFO, "New VM state is HOTPLUG_SAVEAS"); + + vm->set_resched(false); + vmpool->update(vm); + + vm->unlock(); + } + // ------------------------------------------------------------------------- // Get the data of the DataStore for the new image // ------------------------------------------------------------------------- diff --git a/src/tm/TransferManagerDriver.cc b/src/tm/TransferManagerDriver.cc index 416d44091f..8be69538f7 100644 --- a/src/tm/TransferManagerDriver.cc +++ b/src/tm/TransferManagerDriver.cc @@ -132,6 +132,8 @@ void TransferManagerDriver::protocol( break; case VirtualMachine::HOTPLUG_SAVEAS: + case VirtualMachine::HOTPLUG_SAVEAS_POWEROFF: + case VirtualMachine::HOTPLUG_SAVEAS_SUSPENDED: lcm_action = LifeCycleManager::HOTPLUG_SAVEAS_SUCCESS; break; @@ -173,6 +175,8 @@ void TransferManagerDriver::protocol( break; case VirtualMachine::HOTPLUG_SAVEAS: + case VirtualMachine::HOTPLUG_SAVEAS_POWEROFF: + case VirtualMachine::HOTPLUG_SAVEAS_SUSPENDED: lcm_action = LifeCycleManager::HOTPLUG_SAVEAS_FAILURE; break;