From c3741e4fa16328be578c451baebbf7dafc9e2230 Mon Sep 17 00:00:00 2001 From: "Ruben S. Montero" Date: Tue, 9 Jun 2015 00:21:29 +0200 Subject: [PATCH 01/15] feature #3782: Remove snapshot list if empty --- src/vm/VirtualMachine.cc | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/src/vm/VirtualMachine.cc b/src/vm/VirtualMachine.cc index 1e43d1add7..72042516d7 100644 --- a/src/vm/VirtualMachine.cc +++ b/src/vm/VirtualMachine.cc @@ -4434,5 +4434,14 @@ void VirtualMachine::delete_disk_snapshot(int did, int snap_id) } it->second->delete_snapshot(snap_id); + + if (it->second->size() == 0) + { + Snapshots * tmp = it->second; + + snapshots.erase(it); + + delete tmp; + } } From 9d20167c1cec126ab73e31b45a6baef18bd512b1 Mon Sep 17 00:00:00 2001 From: "Ruben S. Montero" Date: Tue, 9 Jun 2015 23:25:10 +0200 Subject: [PATCH 02/15] feautre #3782: Remove SAVE_AS from core --- include/Image.h | 48 +-- include/ImageTemplate.h | 38 +-- include/RequestManagerVirtualMachine.h | 17 - include/VirtualMachine.h | 60 +--- include/VirtualMachinePool.h | 4 +- src/image/Image.cc | 10 +- src/image/ImageManagerActions.cc | 39 +-- src/image/ImageManagerDriver.cc | 41 +-- src/image/ImageTemplate.cc | 3 - src/lcm/LifeCycleActions.cc | 4 +- src/lcm/LifeCycleStates.cc | 46 +-- src/rm/RequestManager.cc | 2 - src/rm/RequestManagerDelete.cc | 49 +-- src/rm/RequestManagerVirtualMachine.cc | 418 ++++++++----------------- src/tm/TransferManager.cc | 82 +---- src/vm/VirtualMachine.cc | 357 ++++++--------------- src/vm/VirtualMachinePool.cc | 13 +- 17 files changed, 333 insertions(+), 898 deletions(-) diff --git a/include/Image.h b/include/Image.h index 1ff370ea52..ee1be2757c 100644 --- a/include/Image.h +++ b/include/Image.h @@ -97,16 +97,16 @@ public: { switch (ob) { - case FILE: return "FILE" ; break; - case CD_ROM: return "CDROM" ; break; - case BLOCK: return "BLOCK" ; break; - case RBD: return "RBD" ; break; - case RBD_CDROM: return "RBD_CDROM" ; break; - case GLUSTER: return "GLUSTER" ; break; - case GLUSTER_CDROM: return "GLUSTER_CDROM" ; break; - case SHEEPDOG: return "SHEEPDOG" ; break; - case SHEEPDOG_CDROM: return "SHEEPDOG_CDROM" ; break; - default: return ""; + case FILE: return "FILE" ; break; + case CD_ROM: return "CDROM" ; break; + case BLOCK: return "BLOCK" ; break; + case RBD: return "RBD" ; break; + case RBD_CDROM: return "RBD_CDROM" ; break; + case GLUSTER: return "GLUSTER" ; break; + case GLUSTER_CDROM: return "GLUSTER_CDROM" ; break; + case SHEEPDOG: return "SHEEPDOG" ; break; + case SHEEPDOG_CDROM: return "SHEEPDOG_CDROM" ; break; + default: return ""; } }; @@ -178,7 +178,7 @@ public: * Returns true if the image is persistent * @return true if the image is persistent */ - bool isPersistent() const + bool is_persistent() const { return (persistent_img == 1); }; @@ -348,35 +348,13 @@ public: */ int set_type(string& _type, string& error); - /** - * Check if the image can be used by other users - * @return true if group or others can access the image - */ - bool isPublic() - { - return (group_u == 1 || other_u == 1); - } - /** * Check if the image is used for saving_as a current one * @return true if the image will be used to save an existing image. */ - bool isSaving() + bool is_saving() { - ImageTemplate * it = static_cast(obj_template); - - return it->is_saving(); - } - - /** - * Check if the image is a hot snapshot - * @return true if image is a hot snapshot - */ - bool isHot() - { - ImageTemplate * it = static_cast(obj_template); - - return it->is_saving_hot(); + return (static_cast(obj_template))->is_saving_hot(); } /** diff --git a/include/ImageTemplate.h b/include/ImageTemplate.h index fc117061b3..45348abe1b 100644 --- a/include/ImageTemplate.h +++ b/include/ImageTemplate.h @@ -59,45 +59,18 @@ public: Template::remove_all_except_restricted(restricted_attributes); }; - bool is_saving() - { - string saving; - - get(saving_attribute, saving); - - return (saving.empty() == false); - } - bool is_saving_hot() { - string save_as_hot; + bool save_as_hot; - get(saving_hot_attribute, save_as_hot); + get("SAVE_AS_HOT", save_as_hot); - return (save_as_hot.empty() == false); - } - - void set_saving() - { - SingleAttribute * attr= new SingleAttribute(saving_attribute, "YES"); - - erase(saving_attribute); - - set(attr); + return save_as_hot; } void set_saving_hot() { - SingleAttribute * attr = new SingleAttribute(saving_hot_attribute,"YES"); - - erase(saving_hot_attribute); - - set(attr); - } - - void unset_saving() - { - erase(saving_attribute); + replace("SAVE_AS_HOT", "YES"); } private: @@ -105,9 +78,6 @@ private: static vector restricted_attributes; - static string saving_attribute; - static string saving_hot_attribute; - bool has_restricted() { return restricted_attributes.size() > 0; diff --git a/include/RequestManagerVirtualMachine.h b/include/RequestManagerVirtualMachine.h index 9a3eb46f06..bb1e849090 100644 --- a/include/RequestManagerVirtualMachine.h +++ b/include/RequestManagerVirtualMachine.h @@ -187,23 +187,6 @@ public: /* ------------------------------------------------------------------------- */ /* ------------------------------------------------------------------------- */ -class VirtualMachineSaveDiskCancel : public RequestManagerVirtualMachine -{ -public: - VirtualMachineSaveDiskCancel(): - RequestManagerVirtualMachine("VirtualMachineSaveDiskCancel", - "Cancels a disk snapshot set by VirtualMachineSaveDisk", - "A:sii"){}; - - ~VirtualMachineSaveDiskCancel(){}; - - void request_execute(xmlrpc_c::paramList const& _paramList, - RequestAttributes& att); -}; - -/* ------------------------------------------------------------------------- */ -/* ------------------------------------------------------------------------- */ - class VirtualMachineMonitoring : public RequestManagerVirtualMachine { public: diff --git a/include/VirtualMachine.h b/include/VirtualMachine.h index 15bb959915..3c3b08d352 100644 --- a/include/VirtualMachine.h +++ b/include/VirtualMachine.h @@ -1270,55 +1270,34 @@ public: int generate_context(string &files, int &disk_id, string& token_password); // ------------------------------------------------------------------------- - // Datastore related functions + // Export Disk related functions (save_as hot) // ------------------------------------------------------------------------- /** - * Gest the associated image to the given disk_id + * Mark the disk that is going to be exported (saved_as) * @param disk_id of the VM - * @param hot is this a save_as hot operation * @param err_str describing the error - * @return -1 if the image cannot saveas + * @return -1 if the image cannot saveas or image_id of current disk */ - int get_image_from_disk(int disk_id, bool hot, string& err_str); + int set_saveas_disk(int disk_id, string& err_str); /** - * Sets the corresponding SAVE_AS state. - * @param disk_id Index of the disk to save - * @param hot is this a save_as hot operation - * @return 0 if the VM can be saved as + * Sets the corresponding state to export the disk. + * @return 0 if the VM can be exported */ - int set_saveas_state(int disk_id, bool hot); + int set_saveas_state(); /** - * Clears the SAVE_AS state, moving the VM to the original state. - * @param disk_id Index of the disk to save - * @param hot is this a save_as hot operation - * @return 0 if the VM was in a SAVE_AS state + * Clears the export state, moving the VM to the original state. + * @return 0 if the VM was in an export state */ - int clear_saveas_state(int disk_id, bool hot); + int clear_saveas_state(); /** - * Set the SAVE_AS attribute for the "disk_id"th disk. - * @param disk_id Index of the disk to save - * @param source to save the disk (SAVE_AS_SOURCE) - * @param img_id ID of the image this disk will be saved to (SAVE_AS). + * Clears the export attributes of the disk being saved as + * @return the ID of the image this disk will be saved to or -1 if it + * is not found. */ - int save_disk(int disk_id, - const string& source, - int img_id); - /** - * Clears the SAVE_AS attribute for the "disk_id"th disk. - * @param disk_id Index of the disk to save - * @return 0 on success, -1 if the disk does not exist - */ - int clear_save_disk(int disk_id); - - /** - * Returns the image ID to be saved-as. - * @param disk_id Index of the disk to save - * @return The image ID, or -1 if the disk is not going to be saved-as - */ - int get_save_disk_image(int disk_id); + int clear_saveas_disk(); /** * Set the SAVE_AS attribute for the "disk_id"th disk. @@ -1336,16 +1315,9 @@ public: * @param error_str describes the error * @return -1 if failure */ - int get_saveas_disk_hot(int& disk_id, string& source, int& image_id); + int get_saveas_disk_hot(int& disk_id, string& source, int& image_id, + string& tm_mad, string& ds_id); - /** - * Clears the save_as attributes of the disk being (hot) saved as - * - * @param img_id ID of the image this disk will be saved to. Can be - * -1 if it is not found - * @return 0 if a disk with (HOTPLUG_)SAVE_AS was cleaned - */ - int cancel_saveas_disk(int& image_id); // ------------------------------------------------------------------------ // Authorization related functions diff --git a/include/VirtualMachinePool.h b/include/VirtualMachinePool.h index 5b260a3424..a819020292 100644 --- a/include/VirtualMachinePool.h +++ b/include/VirtualMachinePool.h @@ -344,10 +344,8 @@ public: * 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); + void delete_attach_disk(int vid); /** * Deletes the NIC that was in the process of being attached diff --git a/src/image/Image.cc b/src/image/Image.cc index 80f1562490..2ff499e3b1 100644 --- a/src/image/Image.cc +++ b/src/image/Image.cc @@ -183,7 +183,7 @@ int Image::insert(SqlDB *db, string& error_str) erase_template_attribute("PATH", path); erase_template_attribute("SOURCE", source); - if (!isSaving()) //Not a saving image + if (!is_saving()) //Not a saving image { if ( source.empty() && path.empty() ) { @@ -624,9 +624,9 @@ int Image::disk_attribute( VectorAttribute * disk, new_disk_type = RBD_CDROM; break; - case SHEEPDOG: - new_disk_type = SHEEPDOG_CDROM; - break; + case SHEEPDOG: + new_disk_type = SHEEPDOG_CDROM; + break; case GLUSTER: new_disk_type = GLUSTER_CDROM; @@ -730,7 +730,7 @@ ImageTemplate * Image::clone_template(const string& new_name) const tmpl->replace("FSTYPE", fs_type); tmpl->replace("SIZE", size_mb); - if ( isPersistent() ) + if ( is_persistent() ) { tmpl->replace("PERSISTENT", "YES"); } diff --git a/src/image/ImageManagerActions.cc b/src/image/ImageManagerActions.cc index 0fabd69811..eefc7f52fc 100644 --- a/src/image/ImageManagerActions.cc +++ b/src/image/ImageManagerActions.cc @@ -113,7 +113,7 @@ int ImageManager::acquire_image(int vm_id, Image *img, string& error) case Image::READY: img->inc_running(vm_id); - if ( img->isPersistent() ) + if ( img->is_persistent() ) { img->set_state(Image::USED_PERS); } @@ -160,11 +160,9 @@ int ImageManager::acquire_image(int vm_id, Image *img, string& error) void ImageManager::release_image(int vm_id, int iid, bool failed) { - Image * img; + ostringstream disk_file, oss; - ostringstream disk_file; - - img = ipool->get(iid,true); + Image * img = ipool->get(iid,true); if ( img == 0 ) { @@ -218,27 +216,10 @@ void ImageManager::release_image(int vm_id, int iid, bool failed) break; case Image::LOCKED: - if ( img->isSaving() ) //SAVE_AS images are LOCKED till released - { - if (failed == true) - { - img->set_state(Image::ERROR); - } - else - { - img->set_state(Image::READY); - } + oss << "Releasing image in wrong state: " + << Image::state_to_str(img->get_state()); - ipool->update(img); - } - else - { - stringstream oss; - oss << "Releasing image in wrong state: " - << Image::state_to_str(img->get_state()); - - NebulaLog::log("ImM", Log::ERROR, oss.str()); - } + NebulaLog::log("ImM", Log::ERROR, oss.str()); img->unlock(); break; @@ -249,7 +230,6 @@ void ImageManager::release_image(int vm_id, int iid, bool failed) case Image::DISABLED: case Image::READY: case Image::ERROR: - ostringstream oss; oss << "Releasing image in wrong state: " << Image::state_to_str(img->get_state()); @@ -639,7 +619,7 @@ int ImageManager::clone_image(int new_id, case Image::READY: img->inc_cloning(new_id); - if (img->isPersistent()) + if (img->is_persistent()) { img->set_state(Image::CLONE); } @@ -738,12 +718,11 @@ int ImageManager::register_image(int iid, const string& ds_data, string& error) { string source = img->get_source(); - if ( img->isSaving() || img->get_type() == Image::DATABLOCK ) + if ( img->is_saving() || img->get_type() == Image::DATABLOCK ) { imd->mkfs(img->get_oid(), *drv_msg); - oss << "Creating disk at " << source - << " of "<< img->get_size() + oss << "Creating disk at " << source << " of "<< img->get_size() << "Mb (type: " << img->get_fstype() << ")"; } else if ( !source.empty() ) //Source in Template diff --git a/src/image/ImageManagerDriver.cc b/src/image/ImageManagerDriver.cc index cb83c6566b..e97fb47889 100644 --- a/src/image/ImageManagerDriver.cc +++ b/src/image/ImageManagerDriver.cc @@ -369,15 +369,12 @@ static int mkfs_action(istringstream& is, string source; Image * image; bool is_saving = false; - bool is_hot = false; string info; - int rc; - int vm_id = -1; - int ds_id = -1; - - int disk_id; + int vm_id = -1; + int ds_id = -1; + int disk_id = -1; VirtualMachine * vm; ostringstream oss; @@ -411,14 +408,13 @@ static int mkfs_action(istringstream& is, return ds_id; } - is_saving = image->isSaving(); - is_hot = image->isHot(); + is_saving = image->is_saving(); ds_id = image->get_ds_id(); if ( is_saving ) { - image->get_template_attribute("SAVED_VM_ID", vm_id); image->get_template_attribute("SAVED_DISK_ID", disk_id); + image->get_template_attribute("SAVED_VM_ID", vm_id); } if ( result == "FAILURE" ) @@ -459,28 +455,12 @@ static int mkfs_action(istringstream& is, goto error_save_get; } - if ( is_hot ) //Saveas hot, trigger disk copy + if ( vm->save_disk_hot(disk_id, source, id) == -1 ) { - rc = vm->save_disk_hot(disk_id, source, id); - - if ( rc == -1 ) - { - goto error_save_state; - } - - tm->trigger(TransferManager::SAVEAS_HOT, vm_id); + goto error_save_state; } - else //setup disk information - { - rc = vm->save_disk(disk_id, source, id); - if ( rc == -1 ) - { - goto error_save_state; - } - - vm->clear_saveas_state(disk_id, is_hot); - } + tm->trigger(TransferManager::SAVEAS_HOT, vm_id); vmpool->update(vm); @@ -530,7 +510,10 @@ error: { if ((vm = vmpool->get(vm_id, true)) != 0) { - vm->clear_saveas_state(disk_id, is_hot); + vm->clear_saveas_state(); + + vm->clear_saveas_disk(); + vmpool->update(vm); vm->unlock(); diff --git a/src/image/ImageTemplate.cc b/src/image/ImageTemplate.cc index 9db95e66fc..599cfd4c78 100644 --- a/src/image/ImageTemplate.cc +++ b/src/image/ImageTemplate.cc @@ -21,8 +21,5 @@ vector ImageTemplate::restricted_attributes; -string ImageTemplate::saving_attribute = "SAVE_AS"; -string ImageTemplate::saving_hot_attribute = "SAVE_AS_HOT"; - /* -------------------------------------------------------------------------- */ /* -------------------------------------------------------------------------- */ diff --git a/src/lcm/LifeCycleActions.cc b/src/lcm/LifeCycleActions.cc index ae844cfa8e..5599c8f4ce 100644 --- a/src/lcm/LifeCycleActions.cc +++ b/src/lcm/LifeCycleActions.cc @@ -938,7 +938,7 @@ void LifeCycleManager::clean_up_vm(VirtualMachine * vm, bool dispose, int& imag break; case VirtualMachine::HOTPLUG_SAVEAS: - vm->cancel_saveas_disk(image_id); + image_id = vm->clear_saveas_disk(); vmpool->update(vm); vm->set_running_etime(the_time); @@ -952,7 +952,7 @@ void LifeCycleManager::clean_up_vm(VirtualMachine * vm, bool dispose, int& imag case VirtualMachine::HOTPLUG_SAVEAS_SUSPENDED: tm->trigger(TransferManager::DRIVER_CANCEL, vid); - vm->cancel_saveas_disk(image_id); + image_id = vm->clear_saveas_disk(); vmpool->update(vm); vm->set_running_etime(the_time); diff --git a/src/lcm/LifeCycleStates.cc b/src/lcm/LifeCycleStates.cc index e8cbe040da..5b958b1f11 100644 --- a/src/lcm/LifeCycleStates.cc +++ b/src/lcm/LifeCycleStates.cc @@ -1232,7 +1232,7 @@ void LifeCycleManager::attach_failure_action(int vid) { vm->unlock(); - vmpool->delete_attach_disk(vid, false); + vmpool->delete_attach_disk(vid); vm = vmpool->get(vid,true); @@ -1282,7 +1282,7 @@ void LifeCycleManager::detach_success_action(int vid) { vm->unlock(); - vmpool->delete_attach_disk(vid, true); + vmpool->delete_attach_disk(vid); vm = vmpool->get(vid,true); @@ -1606,32 +1606,33 @@ void LifeCycleManager::detach_nic_failure_action(int vid) void LifeCycleManager::saveas_hot_success_action(int vid) { - VirtualMachine * vm; - Image * image; - int image_id; int disk_id; + string tm_mad; + string ds_id; string source; - vm = vmpool->get(vid,true); + VirtualMachine * vm = vmpool->get(vid,true); if ( vm == 0 ) { return; } - int rc = vm->get_saveas_disk_hot(disk_id, source, image_id); + int rc = vm->get_saveas_disk_hot(disk_id, source, image_id, tm_mad, ds_id); - if (vm->clear_saveas_state(disk_id, true) == -1) + vm->clear_saveas_disk(); + + vmpool->update(vm); + + if (vm->clear_saveas_state() == -1) { - vm->log("LCM", Log::ERROR, "saveas_hot_success_action, VM in a wrong state"); + vm->log("LCM",Log::ERROR, "saveas_success_action, VM in a wrong state"); vm->unlock(); return; } - vmpool->update(vm); - vm->unlock(); if ( rc != 0 ) @@ -1639,7 +1640,7 @@ void LifeCycleManager::saveas_hot_success_action(int vid) return; } - image = ipool->get(image_id, true); + Image * image = ipool->get(image_id, true); if ( image == 0 ) { @@ -1658,32 +1659,33 @@ void LifeCycleManager::saveas_hot_success_action(int vid) void LifeCycleManager::saveas_hot_failure_action(int vid) { - VirtualMachine * vm; - Image * image; - int image_id; int disk_id; + string tm_mad; + string ds_id; string source; - vm = vmpool->get(vid,true); + VirtualMachine * vm = vmpool->get(vid,true); if ( vm == 0 ) { return; } - int rc = vm->get_saveas_disk_hot(disk_id, source, image_id); + int rc = vm->get_saveas_disk_hot(disk_id, source, image_id, tm_mad, ds_id); - if (vm->clear_saveas_state(disk_id, true) == -1) + vm->clear_saveas_disk(); + + vmpool->update(vm); + + if (vm->clear_saveas_state() == -1) { - vm->log("LCM", Log::ERROR, "saveas_hot_success_action, VM in a wrong state"); + vm->log("LCM",Log::ERROR, "saveas_failure_action, VM in a wrong state"); vm->unlock(); return; } - vmpool->update(vm); - vm->unlock(); if ( rc != 0 ) @@ -1691,7 +1693,7 @@ void LifeCycleManager::saveas_hot_failure_action(int vid) return; } - image = ipool->get(image_id, true); + Image * image = ipool->get(image_id, true); if ( image == 0 ) { diff --git a/src/rm/RequestManager.cc b/src/rm/RequestManager.cc index a390631b72..91dc6fe9df 100644 --- a/src/rm/RequestManager.cc +++ b/src/rm/RequestManager.cc @@ -294,7 +294,6 @@ void RequestManager::register_xml_methods() xmlrpc_c::methodPtr vm_migrate(new VirtualMachineMigrate()); xmlrpc_c::methodPtr vm_action(new VirtualMachineAction()); xmlrpc_c::methodPtr vm_savedisk(new VirtualMachineSaveDisk()); - xmlrpc_c::methodPtr vm_savedisk_cancel(new VirtualMachineSaveDiskCancel()); xmlrpc_c::methodPtr vm_monitoring(new VirtualMachineMonitoring()); xmlrpc_c::methodPtr vm_attach(new VirtualMachineAttach()); xmlrpc_c::methodPtr vm_detach(new VirtualMachineDetach()); @@ -450,7 +449,6 @@ void RequestManager::register_xml_methods() RequestManagerRegistry.addMethod("one.vm.action", vm_action); RequestManagerRegistry.addMethod("one.vm.migrate", vm_migrate); RequestManagerRegistry.addMethod("one.vm.savedisk", vm_savedisk); - RequestManagerRegistry.addMethod("one.vm.savediskcancel", vm_savedisk_cancel); RequestManagerRegistry.addMethod("one.vm.allocate", vm_allocate); RequestManagerRegistry.addMethod("one.vm.info", vm_info); RequestManagerRegistry.addMethod("one.vm.chown", vm_chown); diff --git a/src/rm/RequestManagerDelete.cc b/src/rm/RequestManagerDelete.cc index 5c193e19c7..f9e81085eb 100644 --- a/src/rm/RequestManagerDelete.cc +++ b/src/rm/RequestManagerDelete.cc @@ -179,55 +179,12 @@ int HostDelete::drop(int oid, PoolObjectSQL * object, string& error_msg) int ImageDelete::drop(int oid, PoolObjectSQL * object, string& error_msg) { - Nebula& nd = Nebula::instance(); - ImageManager * imagem = nd.get_imagem(); - VirtualMachinePool * vmpool = nd.get_vmpool(); - - VirtualMachine * vm; - - bool save_as; - int rc, img_id, vm_id, disk_id; - - object->get_template_attribute("SAVE_AS", save_as); - - save_as &= object->get_template_attribute("SAVED_VM_ID", vm_id) & - object->get_template_attribute("SAVED_DISK_ID", disk_id); + Nebula& nd = Nebula::instance(); + ImageManager * imagem = nd.get_imagem(); object->unlock(); - rc = imagem->delete_image(oid, error_msg); - - // ------------------------------------------------------------------------- - // Cancel the disk snapshot - // ------------------------------------------------------------------------- - - if (rc == 0 && save_as) - { - vm = vmpool->get(vm_id, true); - - if (vm == 0) - { - return rc; - } - - if (vm->get_state() == VirtualMachine::DONE) - { - vm->unlock(); - return rc; - } - - img_id = vm->get_save_disk_image(disk_id); - - if ( img_id == oid ) - { - vm->clear_save_disk(disk_id); - vmpool->update(vm); - } - - vm->unlock(); - } - - return rc; + return imagem->delete_image(oid, error_msg); } /* ------------------------------------------------------------------------- */ diff --git a/src/rm/RequestManagerVirtualMachine.cc b/src/rm/RequestManagerVirtualMachine.cc index afa1c4a743..c812424844 100644 --- a/src/rm/RequestManagerVirtualMachine.cc +++ b/src/rm/RequestManagerVirtualMachine.cc @@ -1179,63 +1179,68 @@ void VirtualMachineMigrate::request_execute(xmlrpc_c::paramList const& paramList void VirtualMachineSaveDisk::request_execute(xmlrpc_c::paramList const& paramList, RequestAttributes& att) { - Nebula& nd = Nebula::instance(); + Nebula& nd = Nebula::instance(); ImagePool * ipool = nd.get_ipool(); DatastorePool * dspool = nd.get_dspool(); - int id = xmlrpc_c::value_int(paramList.getInt(1)); - int disk_id = xmlrpc_c::value_int(paramList.getInt(2)); - string img_name = xmlrpc_c::value_string(paramList.getString(3)); - string img_type = xmlrpc_c::value_string(paramList.getString(4)); - bool is_hot = false; //Optional XML-RPC argument - - if ( paramList.size() > 5 ) - { - is_hot = xmlrpc_c::value_boolean(paramList.getBoolean(5)); - } + int id = xmlrpc_c::value_int(paramList.getInt(1)); + int disk_id = xmlrpc_c::value_int(paramList.getInt(2)); + string img_name = xmlrpc_c::value_string(paramList.getString(3)); + string img_type = xmlrpc_c::value_string(paramList.getString(4)); VirtualMachinePool * vmpool = static_cast(pool); + VirtualMachine * vm; Datastore * ds; - int iid; + Image * img; + int iid; + int iid_orig; - string error_str; + string ds_data; + PoolObjectAuth ds_perms; + long long avail; + bool ds_check; string driver; string target; string dev_prefix; + int ds_id; + string ds_name; + long long size; + + string iname_orig; + string iuname_orig; + + Image::ImageType type; + Image::DiskType ds_disk_type; + + ImageTemplate * itemplate; + Template img_usage; + + int rc; + bool rc_auth; + string error; + // ------------------------------------------------------------------------- - // Prepare and check the VM/DISK to be saved_as + // Prepare and check the VM/DISK to be export // ------------------------------------------------------------------------- if ((vm = get_vm(id, att)) == 0) { return; } - if ( vm->set_saveas_state(disk_id, is_hot) != 0 ) + if (vm->set_saveas_state() != 0) { - vm->unlock(); - - failure_response(INTERNAL, - request_error("VM has to be RUNNING, POWEROFF or" - " SUSPENDED to snapshot disks.",""), att); - return; + goto error_state; } - int iid_orig = vm->get_image_from_disk(disk_id, is_hot, error_str); + iid_orig = vm->set_saveas_disk(disk_id, error); - if ( iid_orig == -1 ) + if (iid_orig == -1) { - vm->clear_saveas_state(disk_id, is_hot); - - vm->unlock(); - - failure_response(INTERNAL, - request_error("Cannot use selected DISK", error_str), - att); - return; + goto error_disk; } vmpool->update(vm); @@ -1245,32 +1250,21 @@ void VirtualMachineSaveDisk::request_execute(xmlrpc_c::paramList const& paramLis // ------------------------------------------------------------------------- // Get the data of the Image to be saved // ------------------------------------------------------------------------- - Image * img = ipool->get(iid_orig, true); + img = ipool->get(iid_orig, true); if ( img == 0 ) { - failure_response(NO_EXISTS, - get_error(object_name(PoolObjectSQL::IMAGE), iid_orig), - att); - - if ((vm = vmpool->get(id, true)) != 0) - { - vm->clear_saveas_state(disk_id, is_hot); - - vmpool->update(vm); - vm->unlock(); - } - - return; + goto error_image; } - int ds_id = img->get_ds_id(); - string ds_name = img->get_ds_name(); - long long size = img->get_size(); + ds_id = img->get_ds_id(); + ds_name = img->get_ds_name(); - string iname_orig = img->get_name(); - string iuname_orig = img->get_uname(); - Image::ImageType type = img->get_type(); + size = img->get_size(); + type = img->get_type(); + + iname_orig = img->get_name(); + iuname_orig = img->get_uname(); img->get_template_attribute("DRIVER", driver); img->get_template_attribute("TARGET", target); @@ -1283,74 +1277,39 @@ void VirtualMachineSaveDisk::request_execute(xmlrpc_c::paramList const& paramLis case Image::OS: case Image::DATABLOCK: case Image::CDROM: - break; + break; case Image::KERNEL: case Image::RAMDISK: case Image::CONTEXT: - failure_response(INTERNAL, - request_error("Cannot save_as image of type " + - Image::type_to_str(type), ""), att); - return; + goto error_image_type; } // ------------------------------------------------------------------------- - // Get the data of the DataStore for the new image + // Get the data of the DataStore for the new image & size // ------------------------------------------------------------------------- if ((ds = dspool->get(ds_id, true)) == 0 ) { - failure_response(NO_EXISTS, - get_error(object_name(PoolObjectSQL::DATASTORE), ds_id), - att); - - if ((vm = vmpool->get(id, true)) != 0) - { - vm->clear_saveas_state(disk_id, is_hot); - - vmpool->update(vm); - vm->unlock(); - } - - return; + goto error_ds; } - string ds_data; - PoolObjectAuth ds_perms; - long long avail; - bool ds_check; - ds->get_permissions(ds_perms); ds->to_xml(ds_data); - ds_check = ds->get_avail_mb(avail); - - Image::DiskType ds_disk_type = ds->get_disk_type(); + ds_check = ds->get_avail_mb(avail); + ds_disk_type = ds->get_disk_type(); ds->unlock(); - // ------------------------------------------------------------------------- - // Check Datastore Capacity - // ------------------------------------------------------------------------- if (ds_check && (size > avail)) { - failure_response(ACTION, "Not enough space in datastore", att); - - if ((vm = vmpool->get(id, true)) != 0) - { - vm->clear_saveas_state(disk_id, is_hot); - - vmpool->update(vm); - vm->unlock(); - } - - return; + goto error_size; } // ------------------------------------------------------------------------- // Create a template for the new Image // ------------------------------------------------------------------------- - ImageTemplate * itemplate = new ImageTemplate; - Template img_usage; + itemplate = new ImageTemplate; itemplate->add("NAME", img_name); itemplate->add("SIZE", size); @@ -1358,15 +1317,9 @@ void VirtualMachineSaveDisk::request_execute(xmlrpc_c::paramList const& paramLis itemplate->add("SAVED_IMAGE_ID",iid_orig); itemplate->add("SAVED_DISK_ID",disk_id); itemplate->add("SAVED_VM_ID", id); + itemplate->set_saving_hot(); - itemplate->set_saving(); - - if ( is_hot ) - { - itemplate->set_saving_hot(); - } - - if ( img_type.empty() ) + if (img_type.empty()) { itemplate->add("TYPE", Image::type_to_str(type)); } @@ -1375,17 +1328,17 @@ void VirtualMachineSaveDisk::request_execute(xmlrpc_c::paramList const& paramLis itemplate->add("TYPE", img_type); } - if ( driver.empty() == false ) + if (!driver.empty()) { itemplate->add("DRIVER", driver); } - if ( target.empty() == false ) + if (!target.empty()) { itemplate->add("TARGET", target); } - if ( dev_prefix.empty() == false ) + if (!dev_prefix.empty()) { itemplate->add("DEV_PREFIX", dev_prefix); } @@ -1396,7 +1349,7 @@ void VirtualMachineSaveDisk::request_execute(xmlrpc_c::paramList const& paramLis // ------------------------------------------------------------------------- // Authorize the operation & check quotas // ------------------------------------------------------------------------- - bool rc_auth = vm_authorization(id, itemplate, 0, att, 0,&ds_perms,auth_op); + rc_auth = vm_authorization(id, itemplate, 0, att, 0,&ds_perms,auth_op); if ( rc_auth == true ) { @@ -1405,216 +1358,109 @@ void VirtualMachineSaveDisk::request_execute(xmlrpc_c::paramList const& paramLis if ( rc_auth == false) { - delete itemplate; - - if ((vm = vmpool->get(id, true)) != 0) - { - vm->clear_saveas_state(disk_id, is_hot); - - vmpool->update(vm); - vm->unlock(); - } - - return; + goto error_auth; } // ------------------------------------------------------------------------- // Create the image // ------------------------------------------------------------------------- - int rc = ipool->allocate(att.uid, - att.gid, - att.uname, - att.gname, - att.umask, - itemplate, - ds_id, - ds_name, - ds_disk_type, - ds_data, - Datastore::IMAGE_DS, - -1, - &iid, - error_str); + rc = ipool->allocate(att.uid, + att.gid, + att.uname, + att.gname, + att.umask, + itemplate, + ds_id, + ds_name, + ds_disk_type, + ds_data, + Datastore::IMAGE_DS, + -1, + &iid, + error); if (rc < 0) { - quota_rollback(&img_usage, Quotas::DATASTORE, att); - - if ((vm = vmpool->get(id, true)) != 0) - { - vm->clear_saveas_state(disk_id, is_hot); - - vmpool->update(vm); - vm->unlock(); - } - - failure_response(INTERNAL, - allocate_error(PoolObjectSQL::IMAGE, error_str), att); - return; + goto error_allocate; } ds = dspool->get(ds_id, true); - if ( ds != 0 ) // TODO: error otherwise or leave image in ERROR? + if (ds == 0) { - ds->add_image(iid); - - dspool->update(ds); - - ds->unlock(); + goto error_ds_removed; } + ds->add_image(iid); + + dspool->update(ds); + + ds->unlock(); + success_response(iid, att); -} -/* -------------------------------------------------------------------------- */ -/* -------------------------------------------------------------------------- */ +error_state: + vm->unlock(); -void VirtualMachineSaveDiskCancel::request_execute( - xmlrpc_c::paramList const& paramList, - RequestAttributes& att) -{ - Nebula& nd = Nebula::instance(); + failure_response(INTERNAL,request_error("VM has to be RUNNING, POWEROFF or " + "SUSPENDED to export disks.",""), att); + return; - AclManager * aclm = nd.get_aclm(); - ImageManager * imagem = nd.get_imagem(); - ImagePool * ipool = nd.get_ipool(); - Image * img; - int img_id; +error_disk: + vm->clear_saveas_state(); - VirtualMachinePool * vmpool = static_cast(pool); - VirtualMachine * vm; - - string error_str; - - int id = xmlrpc_c::value_int(paramList.getInt(1)); - int disk_id = xmlrpc_c::value_int(paramList.getInt(2)); - - // ------------------------------------------------------------------------- - // Authorize the VM operation - // ------------------------------------------------------------------------- - - if (att.uid != UserPool::ONEADMIN_ID) - { - PoolObjectAuth vm_perms; - PoolObjectAuth img_perms; - - if ((vm = get_vm(id, att)) == 0) - { - return; - } - - vm->get_permissions(vm_perms); - - img_id = vm->get_save_disk_image(disk_id); - - vm->unlock(); - - AuthRequest ar(att.uid, att.group_ids); - - ar.add_auth(auth_op, vm_perms); // MANAGE VM - - img = ipool->get(img_id, true); - - if ( img != 0 ) - { - img->get_permissions(img_perms); - - img->unlock(); - - ar.add_auth(AuthRequest::MANAGE, img_perms); // MANAGE IMAGE - } - - if (UserPool::authorize(ar) == -1) - { - failure_response(AUTHORIZATION, - authorization_error(ar.message, att), - att); - - return; - } - } - - // ------------------------------------------------------------------------- - // Check the VM state - // ------------------------------------------------------------------------- - - if ((vm = get_vm(id, att)) == 0) - { - return; - } - - if ((vm->get_state() != VirtualMachine::ACTIVE || - (vm->get_lcm_state() != VirtualMachine::RUNNING && - vm->get_lcm_state() != VirtualMachine::UNKNOWN) ) && - vm->get_state() != VirtualMachine::POWEROFF && - vm->get_state() != VirtualMachine::SUSPENDED) - { - failure_response(ACTION, - request_error("Wrong state to perform action",""), - att); - - vm->unlock(); - return; - } - - // ------------------------------------------------------------------------- - // Cancel the disk snapshot - // ------------------------------------------------------------------------- - - img_id = vm->get_save_disk_image(disk_id); - - if ( img_id == -1 ) - { - ostringstream oss; - oss << "Disk with ID [" << disk_id << "] is not going to be saved"; - - failure_response(ACTION, - request_error(oss.str(), ""), - att); - - vm->unlock(); - - return; - } - - vm->clear_save_disk(disk_id); - - vmpool->update(vm); + vm->clear_saveas_disk(); vm->unlock(); - // ------------------------------------------------------------------------- - // Delete the target Image - // ------------------------------------------------------------------------- + failure_response(INTERNAL,request_error("Cannot use DISK", error), att); + return; - img = ipool->get(img_id, true); +error_image: + failure_response(NO_EXISTS, get_error(object_name(PoolObjectSQL::IMAGE), + iid_orig), att); + goto error_common; - if ( img != 0 ) +error_image_type: + failure_response(INTERNAL, request_error("Cannot save_as image of type " + + Image::type_to_str(type), ""), att); + goto error_common; + +error_ds: + failure_response(NO_EXISTS, get_error(object_name(PoolObjectSQL::DATASTORE), + ds_id), att); + goto error_common; + +error_size: + failure_response(ACTION, "Not enough space in datastore", att); + goto error_common; + +error_auth: + delete itemplate; + goto error_common; + +error_allocate: + quota_rollback(&img_usage, Quotas::DATASTORE, att); + failure_response(INTERNAL, allocate_error(PoolObjectSQL::IMAGE, error),att); + goto error_common; + +error_ds_removed: + failure_response(NO_EXISTS,get_error(object_name(PoolObjectSQL::DATASTORE), + ds_id), att); + goto error_common; + +error_common: + if ((vm = vmpool->get(id, true)) != 0) { - img->unlock(); + vm->clear_saveas_state(); - int rc = imagem->delete_image(img_id, error_str); + vm->clear_saveas_disk(); - if (rc != 0) - { - ostringstream oss; - oss << "The snapshot was canceled, but " - << object_name(PoolObjectSQL::IMAGE) << " [" << img_id - << "] could not be deleted: " << error_str; + vmpool->update(vm); - failure_response(INTERNAL, - request_error(oss.str(), ""), - att); - - return; - } - - aclm->del_resource_rules(img_id, PoolObjectSQL::IMAGE); + vm->unlock(); } - // TODO: Delete the cloned template - - success_response(id, att); + return; } /* -------------------------------------------------------------------------- */ diff --git a/src/tm/TransferManager.cc b/src/tm/TransferManager.cc index 84be34350d..e670c82ce5 100644 --- a/src/tm/TransferManager.cc +++ b/src/tm/TransferManager.cc @@ -1233,27 +1233,20 @@ void TransferManager::epilog_transfer_command( const VectorAttribute * disk, ostream& xfr) { - string save; - string tm_mad; int disk_id; - disk->vector_value("DISK_ID", disk_id); - save = disk->vector_value("SAVE"); + string save = disk->vector_value("SAVE"); + + disk->vector_value("DISK_ID", disk_id); transform(save.begin(),save.end(),save.begin(),(int(*)(int))toupper); if ( save == "YES" ) { - string source; - string save_source; - string ds_id; - - source = disk->vector_value("SOURCE"); - save_source = disk->vector_value("SAVE_AS_SOURCE"); - - tm_mad = disk->vector_value("TM_MAD"); - ds_id = disk->vector_value("DATASTORE_ID"); + string source = disk->vector_value("SOURCE"); + string tm_mad = disk->vector_value("TM_MAD"); + string ds_id = disk->vector_value("DATASTORE_ID"); if ( ds_id.empty() || tm_mad.empty() ) { @@ -1261,17 +1254,12 @@ void TransferManager::epilog_transfer_command( return; } - if (source.empty() && save_source.empty()) + if (source.empty()) { vm->log("TM", Log::ERROR, "No SOURCE to save disk image"); return; } - if (!save_source.empty())//Use the save_as_source instead - { - source = save_source; - } - //MVDS tm_mad hostname:remote_system_dir/disk.0 vmid dsid xfr << "MVDS " << tm_mad << " " @@ -1284,6 +1272,8 @@ void TransferManager::epilog_transfer_command( } else //No saving disk { + string tm_mad; + int ds_id_i; int vv_rc = 0; @@ -2063,30 +2053,20 @@ void TransferManager::saveas_hot_action(int vid) { int disk_id; int image_id; - string save_source; - - string save; + string source; string tm_mad; string ds_id; - int num; - int disk_id_iter; - ostringstream os; ofstream xfr; string xfr_name; - string source; - - const VectorAttribute * disk; - vector attrs; - VirtualMachine * vm; - Nebula& nd = Nebula::instance(); - const TransferManagerDriver * tm_md; + Nebula& nd = Nebula::instance(); + // ------------------------------------------------------------------------ // Setup & Transfer script // ------------------------------------------------------------------------ @@ -2104,7 +2084,7 @@ void TransferManager::saveas_hot_action(int vid) goto error_common; } - if (vm->get_saveas_disk_hot(disk_id, save_source, image_id) == -1) + if (vm->get_saveas_disk_hot(disk_id, source, image_id, tm_mad, ds_id) != 0) { vm->log("TM", Log::ERROR,"Could not get disk information to saveas it"); goto error_common; @@ -2117,40 +2097,6 @@ void TransferManager::saveas_hot_action(int vid) goto error_driver; } - num = vm->get_template_attribute("DISK",attrs); - - for (int i=0 ; i < num ; i++) - { - disk = dynamic_cast(attrs[i]); - - if ( disk == 0 ) - { - continue; - } - - disk->vector_value("DISK_ID", disk_id_iter); - - if (disk_id == disk_id_iter) - { - tm_mad = disk->vector_value("TM_MAD"); - ds_id = disk->vector_value("DATASTORE_ID"); - - break; - } - } - - if ( ds_id.empty() || tm_mad.empty() ) - { - vm->log("TM", Log::ERROR, "No DS_ID or TM_MAD to save disk image"); - goto error_common; - } - - if (save_source.empty()) - { - vm->log("TM", Log::ERROR, "No SOURCE to save disk image"); - goto error_common; - } - xfr_name = vm->get_transfer_file() + ".saveas_hot"; xfr.open(xfr_name.c_str(),ios::out | ios::trunc); @@ -2164,7 +2110,7 @@ void TransferManager::saveas_hot_action(int vid) << tm_mad << " " << vm->get_hostname() << ":" << vm->get_remote_system_dir() << "/disk." << disk_id << " " - << save_source << " " + << source << " " << vm->get_oid() << " " << ds_id << endl; diff --git a/src/vm/VirtualMachine.cc b/src/vm/VirtualMachine.cc index 72042516d7..6c08419a36 100644 --- a/src/vm/VirtualMachine.cc +++ b/src/vm/VirtualMachine.cc @@ -3180,162 +3180,6 @@ int VirtualMachine::generate_context(string &files, int &disk_id, return 1; } -/* -------------------------------------------------------------------------- */ - -int VirtualMachine::get_image_from_disk(int disk_id, bool hot, string& err_str) -{ - int iid = -1; - int rc; - - VectorAttribute * disk; - - ostringstream oss; - - disk = get_disk(disk_id); - - if ( disk == 0 ) - { - goto error_not_found; - } - - if(!((disk->vector_value("SAVE_AS")).empty())) - { - goto error_saved; - } - - if(!(disk->vector_value("PERSISTENT").empty()) && !hot) - { - goto error_persistent; - } - - rc = disk->vector_value("IMAGE_ID", iid); - - if ( rc != 0 ) - { - goto error_image_id; - } - - return iid; - -error_persistent: - oss << "Source image for DISK " << disk_id << " is persistent."; - goto error_common; - -error_saved: - oss << "The DISK " << disk_id << " is already going to be saved."; - goto error_common; - -error_image_id: - oss << "The DISK " << disk_id << " does not have a valid IMAGE_ID."; - goto error_common; - -error_not_found: - oss << "The DISK " << disk_id << " does not exist for VM " << oid << "."; - -error_common: - err_str = oss.str(); - - return -1; -} - -/* -------------------------------------------------------------------------- */ -/* -------------------------------------------------------------------------- */ - -int VirtualMachine::set_saveas_state(int disk_id, bool hot) -{ - VectorAttribute* disk; - - switch (state) - { - case ACTIVE: - switch (lcm_state) - { - case RUNNING: - lcm_state = HOTPLUG_SAVEAS; - break; - - default: - return -1; - } - break; - - case POWEROFF: - state = ACTIVE; - lcm_state = HOTPLUG_SAVEAS_POWEROFF; - break; - - case SUSPENDED: - state = ACTIVE; - lcm_state = HOTPLUG_SAVEAS_SUSPENDED; - break; - - default: - return -1; - } - - disk = get_disk(disk_id); - - if ( disk != 0 ) - { - if (hot) - { - disk->replace("HOTPLUG_SAVE_AS_ACTIVE", "YES"); - } - else - { - disk->replace("SAVE_AS_ACTIVE", "YES"); - } - } - - return 0; -} - -/* -------------------------------------------------------------------------- */ -/* -------------------------------------------------------------------------- */ - -int VirtualMachine::clear_saveas_state(int disk_id, bool hot) -{ - VectorAttribute * disk; - - disk = get_disk(disk_id); - - if (disk != 0) - { - if (hot) - { - disk->remove("HOTPLUG_SAVE_AS_ACTIVE"); - disk->remove("HOTPLUG_SAVE_AS"); - disk->remove("HOTPLUG_SAVE_AS_SOURCE"); - } - else - { - disk->remove("SAVE_AS_ACTIVE"); - } - } - - switch (lcm_state) - { - case HOTPLUG_SAVEAS: - lcm_state = RUNNING; - break; - - case HOTPLUG_SAVEAS_POWEROFF: - state = POWEROFF; - lcm_state = LCM_INIT; - break; - - case HOTPLUG_SAVEAS_SUSPENDED: - state = SUSPENDED; - lcm_state = LCM_INIT; - break; - - default: - return -1; - } - - return 0; -} - /* -------------------------------------------------------------------------- */ /* -------------------------------------------------------------------------- */ @@ -3372,27 +3216,57 @@ const VectorAttribute* VirtualMachine::get_disk(int disk_id) const /* -------------------------------------------------------------------------- */ /* -------------------------------------------------------------------------- */ -int VirtualMachine::save_disk(int disk_id, - const string& source, - int img_id) +int VirtualMachine::set_saveas_disk(int disk_id, string& err_str) { - VectorAttribute * disk; + int iid = -1; - if (lcm_state != HOTPLUG_SAVEAS && lcm_state != HOTPLUG_SAVEAS_SUSPENDED - && lcm_state != HOTPLUG_SAVEAS_POWEROFF ) + VectorAttribute * disk = get_disk(disk_id); + + if ( disk == 0 ) { + err_str = "DISK does not exist."; return -1; } - disk = get_disk(disk_id); - - if ( disk != 0 ) + if ( disk->vector_value("IMAGE_ID", iid) != 0 ) { - disk->replace("SAVE_AS_SOURCE", source); + err_str = "DISK does not have a valid IMAGE_ID."; + return -1; + } - disk->replace("SAVE_AS", img_id); + disk->replace("HOTPLUG_SAVE_AS_ACTIVE", "YES"); - disk->replace("SAVE", "YES"); + return iid; +} + +/* -------------------------------------------------------------------------- */ +/* -------------------------------------------------------------------------- */ + +int VirtualMachine::set_saveas_state() +{ + switch (state) + { + case ACTIVE: + if (lcm_state != RUNNING) + { + return -1; + } + + lcm_state = HOTPLUG_SAVEAS; + break; + + case POWEROFF: + state = ACTIVE; + lcm_state = HOTPLUG_SAVEAS_POWEROFF; + break; + + case SUSPENDED: + state = ACTIVE; + lcm_state = HOTPLUG_SAVEAS_SUSPENDED; + break; + + default: + return -1; } return 0; @@ -3401,46 +3275,68 @@ int VirtualMachine::save_disk(int disk_id, /* -------------------------------------------------------------------------- */ /* -------------------------------------------------------------------------- */ -int VirtualMachine::clear_save_disk(int disk_id) +int VirtualMachine::clear_saveas_state() { - VectorAttribute * disk; - - disk = get_disk(disk_id); - - if ( disk != 0 ) + switch (lcm_state) { - disk->remove("SAVE_AS_SOURCE"); - disk->remove("SAVE_AS"); - disk->replace("SAVE", "NO"); + case HOTPLUG_SAVEAS: + lcm_state = RUNNING; + break; - return 0; + case HOTPLUG_SAVEAS_POWEROFF: + state = POWEROFF; + lcm_state = LCM_INIT; + break; + + case HOTPLUG_SAVEAS_SUSPENDED: + state = SUSPENDED; + lcm_state = LCM_INIT; + break; + + default: + return -1; } - return -1; + return 0; } /* -------------------------------------------------------------------------- */ /* -------------------------------------------------------------------------- */ -int VirtualMachine::get_save_disk_image(int disk_id) +int VirtualMachine::clear_saveas_disk() { - VectorAttribute * disk; - bool save; - int img_id = -1; + vector disks; + VectorAttribute * disk; - disk = get_disk(disk_id); + int num_disks, image_id; + bool active; - if ( disk != 0 ) + num_disks = obj_template->get("DISK", disks); + + for(int i=0; ivector_value("SAVE", save); + disk = dynamic_cast(disks[i]); - if (save) + if ( disk == 0 ) { - disk->vector_value("SAVE_AS", img_id); + continue; + } + + disk->vector_value("HOTPLUG_SAVE_AS_ACTIVE", active); + + if (active) + { + disk->vector_value("HOTPLUG_SAVE_AS", image_id); + + disk->remove("HOTPLUG_SAVE_AS_ACTIVE"); + disk->remove("HOTPLUG_SAVE_AS"); + disk->remove("HOTPLUG_SAVE_AS_SOURCE"); + + return image_id; } } - return img_id; + return -1; } /* -------------------------------------------------------------------------- */ @@ -3450,22 +3346,22 @@ int VirtualMachine::save_disk_hot(int disk_id, const string& source, int img_id) { - VectorAttribute * disk; - if (lcm_state != HOTPLUG_SAVEAS && lcm_state != HOTPLUG_SAVEAS_SUSPENDED && lcm_state != HOTPLUG_SAVEAS_POWEROFF ) { return -1; } - disk = get_disk(disk_id); + VectorAttribute * disk = get_disk(disk_id); - if ( disk != 0 ) + if ( disk == 0 ) { - disk->replace("HOTPLUG_SAVE_AS", img_id); - disk->replace("HOTPLUG_SAVE_AS_SOURCE", source); + return -1; } + disk->replace("HOTPLUG_SAVE_AS", img_id); + disk->replace("HOTPLUG_SAVE_AS_SOURCE", source); + return 0; } @@ -3473,7 +3369,7 @@ int VirtualMachine::save_disk_hot(int disk_id, /* -------------------------------------------------------------------------- */ int VirtualMachine::get_saveas_disk_hot(int& disk_id, string& source, - int& image_id) + int& image_id, string& tm_mad, string& ds_id) { vector disks; VectorAttribute * disk; @@ -3494,78 +3390,19 @@ int VirtualMachine::get_saveas_disk_hot(int& disk_id, string& source, if ( disk->vector_value("HOTPLUG_SAVE_AS_ACTIVE") == "YES" ) { - source = disk->vector_value("HOTPLUG_SAVE_AS_SOURCE"); - - rc = disk->vector_value("HOTPLUG_SAVE_AS", image_id); + rc = disk->vector_value("HOTPLUG_SAVE_AS_SOURCE", source); + rc += disk->vector_value("HOTPLUG_SAVE_AS", image_id); rc += disk->vector_value("DISK_ID", disk_id); + rc += disk->vector_value("DATASTORE_ID", ds_id); + rc += disk->vector_value("TM_MAD", tm_mad); - if ( rc != 0 || source.empty() ) - { - return -1; - } - - return 0; + return rc; } } return -1; } -/* -------------------------------------------------------------------------- */ -/* -------------------------------------------------------------------------- */ - -int VirtualMachine::cancel_saveas_disk(int& image_id) -{ - vector disks; - VectorAttribute * disk; - - int num_disks; - - num_disks = obj_template->get("DISK", disks); - - bool active, hot_active; - - image_id = -1; - - for(int i=0; i(disks[i]); - - if ( disk == 0 ) - { - continue; - } - - disk->vector_value("SAVE_AS_ACTIVE", active); - disk->vector_value("HOTPLUG_SAVE_AS_ACTIVE", hot_active); - - if (active) - { - disk->vector_value("SAVE_AS", image_id); - - disk->remove("SAVE_AS_ACTIVE"); - disk->remove("SAVE_AS_SOURCE"); - disk->remove("SAVE_AS"); - - disk->replace("SAVE", "NO"); - - return 0; - } - - if (hot_active) - { - disk->vector_value("HOTPLUG_SAVE_AS", image_id); - - disk->remove("HOTPLUG_SAVE_AS_ACTIVE"); - disk->remove("HOTPLUG_SAVE_AS"); - disk->remove("HOTPLUG_SAVE_AS_SOURCE"); - - return 0; - } - } - - return -1; -} /* -------------------------------------------------------------------------- */ /* -------------------------------------------------------------------------- */ diff --git a/src/vm/VirtualMachinePool.cc b/src/vm/VirtualMachinePool.cc index 7b413f9db2..43f83fd109 100644 --- a/src/vm/VirtualMachinePool.cc +++ b/src/vm/VirtualMachinePool.cc @@ -1028,7 +1028,7 @@ int VirtualMachinePool::calculate_showback( /* -------------------------------------------------------------------------- */ /* -------------------------------------------------------------------------- */ -void VirtualMachinePool::delete_attach_disk(int vid, bool release_save_as) +void VirtualMachinePool::delete_attach_disk(int vid) { VirtualMachine * vm; VectorAttribute * disk; @@ -1076,17 +1076,6 @@ void VirtualMachinePool::delete_attach_disk(int vid, bool release_save_as) } 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 { From ce85188042d04d23b5ff2a138750080eec9117be Mon Sep 17 00:00:00 2001 From: "Ruben S. Montero" Date: Wed, 10 Jun 2015 01:30:22 +0200 Subject: [PATCH 03/15] feature #3782: Changes in OCA (Ruby) and CLI. Updated direct references to OCA methods --- include/RequestManagerVirtualMachine.h | 12 +++---- src/cli/onevm | 31 +++++-------------- src/cloud/ec2/lib/EC2QueryServer.rb | 7 ++--- src/cloud/ec2/lib/ebs.rb | 5 ++- src/image/ImageManagerActions.cc | 23 +++++--------- src/lcm/LifeCycleStates.cc | 14 ++++++--- src/oca/ruby/opennebula/virtual_machine.rb | 28 +++-------------- src/rm/RequestManager.cc | 4 +-- src/rm/RequestManagerVirtualMachine.cc | 4 ++- .../OpenNebulaJSON/VirtualMachineJSON.rb | 10 +----- 10 files changed, 47 insertions(+), 91 deletions(-) diff --git a/include/RequestManagerVirtualMachine.h b/include/RequestManagerVirtualMachine.h index bb1e849090..33f606d50e 100644 --- a/include/RequestManagerVirtualMachine.h +++ b/include/RequestManagerVirtualMachine.h @@ -170,15 +170,15 @@ public: /* ------------------------------------------------------------------------- */ /* ------------------------------------------------------------------------- */ -class VirtualMachineSaveDisk : public RequestManagerVirtualMachine +class VirtualMachineDiskExport : public RequestManagerVirtualMachine { public: - VirtualMachineSaveDisk(): - RequestManagerVirtualMachine("VirtualMachineSaveDisk", - "Saves a disk from virtual machine as a new image", - "A:siissb"){}; + VirtualMachineDiskExport(): + RequestManagerVirtualMachine("VirtualMachineDiskExport", + "Exports a disk from virtual machine as a new image", + "A:siiss"){}; - ~VirtualMachineSaveDisk(){}; + ~VirtualMachineDiskExport(){}; void request_execute(xmlrpc_c::paramList const& _paramList, RequestAttributes& att); diff --git a/src/cli/onevm b/src/cli/onevm index 4ae4f74cb6..e97023ea3b 100755 --- a/src/cli/onevm +++ b/src/cli/onevm @@ -298,19 +298,16 @@ cmd=CommandParser::CmdParser.new(ARGV) do end end - disk_snapshot_desc = <<-EOT.unindent - Sets the specified VM disk to be saved in a new Image. The Image is - created immediately, but the contents are saved only after the VM is - shut down gracefully (i.e., using 'onevm shutdown' and not - 'onevm delete') - - If '--live' is specified, the Image will be saved immediately. + disk_export_desc = <<-EOT.unindent + Exports the specified VM disk to a new Image. The Image is + created immediately, and the contents of the VM disk will be saved to + it. States: ANY EOT - command :"disk-snapshot", disk_snapshot_desc, :vmid, :diskid, :img_name, - :options=>[TYPE, OneVMHelper::LIVE] do + command :"disk-export", disk_export_desc, :vmid, :diskid, :img_name, + :options=>[TYPE] do disk_id = args[1].to_i image_name = args[2] image_type = options[:type] || "" @@ -319,8 +316,7 @@ cmd=CommandParser::CmdParser.new(ARGV) do "the image #{image_name}" helper.perform_action(args[0],options,verbose) do |vm| - res = vm.disk_snapshot(disk_id, image_name, image_type, - options[:live]==true) + res = vm.disk_export(disk_id, image_name, image_type) if !OpenNebula.is_error?(res) puts "Image ID: #{res}" @@ -330,19 +326,6 @@ cmd=CommandParser::CmdParser.new(ARGV) do end end - disk_snapshot_cancel_desc = <<-EOT.unindent - Cancels a deferred disk snapshot that has been set by disk-snapshot. - The target image is also deleted. - - States: ANY - EOT - - command :"disk-snapshot-cancel", disk_snapshot_cancel_desc, :vmid, :diskid do - helper.perform_action(args[0],options,"disk snapshot canceled") do |vm| - vm.disk_snapshot_cancel(args[1].to_i) - end - end - shutdown_desc = <<-EOT.unindent Shuts down the given VM. The VM life cycle will end. diff --git a/src/cloud/ec2/lib/EC2QueryServer.rb b/src/cloud/ec2/lib/EC2QueryServer.rb index c5c5ed0519..5381e4443c 100644 --- a/src/cloud/ec2/lib/EC2QueryServer.rb +++ b/src/cloud/ec2/lib/EC2QueryServer.rb @@ -218,10 +218,9 @@ class EC2QueryServer < CloudServer return rc end - image_id = vm.disk_snapshot(1, - params["Name"], - OpenNebula::Image::IMAGE_TYPES[0], - true) + image_id = vm.disk_export(1, + params["Name"], + OpenNebula::Image::IMAGE_TYPES[0]) # TODO Add AMI Tags # TODO A new persistent image should be created for each instance diff --git a/src/cloud/ec2/lib/ebs.rb b/src/cloud/ec2/lib/ebs.rb index c09e7ccc5c..9f6807ff87 100644 --- a/src/cloud/ec2/lib/ebs.rb +++ b/src/cloud/ec2/lib/ebs.rb @@ -302,10 +302,9 @@ module EBS disk_id = vm["TEMPLATE/DISK[IMAGE_ID=#{image_id}]/DISK_ID"] if !disk_id.nil? - snapshot_id = vm.disk_snapshot(disk_id.to_i, + snapshot_id = vm.disk_export(disk_id.to_i, params["Description"]||ImageEC2.generate_uuid, - OpenNebula::Image::IMAGE_TYPES[image["TYPE"].to_i], - true) + OpenNebula::Image::IMAGE_TYPES[image["TYPE"].to_i]) if OpenNebula::is_error?(snapshot_id) return snapshot_id diff --git a/src/image/ImageManagerActions.cc b/src/image/ImageManagerActions.cc index eefc7f52fc..6846353ac8 100644 --- a/src/image/ImageManagerActions.cc +++ b/src/image/ImageManagerActions.cc @@ -160,7 +160,7 @@ int ImageManager::acquire_image(int vm_id, Image *img, string& error) void ImageManager::release_image(int vm_id, int iid, bool failed) { - ostringstream disk_file, oss; + ostringstream oss; Image * img = ipool->get(iid,true); @@ -245,11 +245,7 @@ void ImageManager::release_image(int vm_id, int iid, bool failed) void ImageManager::release_cloning_image(int iid, int clone_img_id) { - Image * img; - - ostringstream disk_file; - - img = ipool->get(iid,true); + Image * img = ipool->get(iid,true); if ( img == 0 ) { @@ -276,15 +272,13 @@ void ImageManager::release_cloning_image(int iid, int clone_img_id) { case Image::USED: case Image::CLONE: - if (img->dec_cloning(clone_img_id) == 0 && img->get_running() == 0) { img->set_state(Image::READY); } ipool->update(img); - - break; + break; case Image::DELETE: case Image::INIT: @@ -293,14 +287,13 @@ void ImageManager::release_cloning_image(int iid, int clone_img_id) case Image::ERROR: case Image::USED_PERS: case Image::LOCKED: + ostringstream oss; - ostringstream oss; - oss << "Releasing image in wrong state: " - << Image::state_to_str(img->get_state()); + oss << "Releasing image in wrong state: " + << Image::state_to_str(img->get_state()); - NebulaLog::log("ImM", Log::ERROR, oss.str()); - - break; + NebulaLog::log("ImM", Log::ERROR, oss.str()); + break; } img->unlock(); diff --git a/src/lcm/LifeCycleStates.cc b/src/lcm/LifeCycleStates.cc index 5b958b1f11..7c350351d2 100644 --- a/src/lcm/LifeCycleStates.cc +++ b/src/lcm/LifeCycleStates.cc @@ -1623,16 +1623,19 @@ void LifeCycleManager::saveas_hot_success_action(int vid) vm->clear_saveas_disk(); - vmpool->update(vm); - if (vm->clear_saveas_state() == -1) { vm->log("LCM",Log::ERROR, "saveas_success_action, VM in a wrong state"); + + vmpool->update(vm); + vm->unlock(); return; } + vmpool->update(vm); + vm->unlock(); if ( rc != 0 ) @@ -1676,16 +1679,19 @@ void LifeCycleManager::saveas_hot_failure_action(int vid) vm->clear_saveas_disk(); - vmpool->update(vm); - if (vm->clear_saveas_state() == -1) { vm->log("LCM",Log::ERROR, "saveas_failure_action, VM in a wrong state"); + + vmpool->update(vm); + vm->unlock(); return; } + vmpool->update(vm); + vm->unlock(); if ( rc != 0 ) diff --git a/src/oca/ruby/opennebula/virtual_machine.rb b/src/oca/ruby/opennebula/virtual_machine.rb index 0b1d91a839..71dfda1ca7 100644 --- a/src/oca/ruby/opennebula/virtual_machine.rb +++ b/src/oca/ruby/opennebula/virtual_machine.rb @@ -29,8 +29,6 @@ module OpenNebula :action => "vm.action", :migrate => "vm.migrate", :deploy => "vm.deploy", - :savedisk => "vm.savedisk", - :savediskcancel => "vm.savediskcancel", :chown => "vm.chown", :chmod => "vm.chmod", :monitoring => "vm.monitoring", @@ -45,6 +43,7 @@ module OpenNebula :attachnic => "vm.attachnic", :detachnic => "vm.detachnic", :recover => "vm.recover", + :diskexport => "vm.diskexport", :disksnapshotcreate => "vm.disksnapshotcreate", :disksnapshotrevert => "vm.disksnapshotrevert", :disksnapshotdelete => "vm.disksnapshotdelete" @@ -468,36 +467,20 @@ module OpenNebula # disk will be saved # @param image_type [String] Type of the new image. Set to empty string # to use the default type - # @param hot [true|false] True to save the disk immediately, false will - # perform the operation when the VM shuts down # # @return [Integer, OpenNebula::Error] the new Image ID in case of # success, error otherwise - def disk_snapshot(disk_id, image_name, image_type="", hot=false) + def disk_export(disk_id, image_name, image_type="") return Error.new('ID not defined') if !@pe_id - rc = @client.call(VM_METHODS[:savedisk], + rc = @client.call(VM_METHODS[:diskexport], @pe_id, disk_id, image_name, - image_type, - hot) + image_type) return rc end - # @deprecated use {#disk_snapshot} - def save_as(disk_id, image_name, image_type="", hot=false) - return disk_snapshot(disk_id, image_name, image_type, hot) - end - - # Cancels a deferred snapshot that has been set by disk_snapshot. - # The target image is also deleted. - def disk_snapshot_cancel(disk_id) - return call(VM_METHODS[:savediskcancel], - @pe_id, - disk_id) - end - # Resize the VM # # @param capacity_template [String] Template containing the new capacity @@ -784,8 +767,7 @@ module OpenNebula image_id = disk["IMAGE_ID"] if !image_id.nil? && !image_id.empty? - rc = disk_snapshot(disk_id.to_i, "#{name}-disk-#{disk_id}", - "", true) + rc = disk_export(disk_id.to_i,"#{name}-disk-#{disk_id}","") return rc if OpenNebula.is_error?(rc) diff --git a/src/rm/RequestManager.cc b/src/rm/RequestManager.cc index 91dc6fe9df..72a29c3d91 100644 --- a/src/rm/RequestManager.cc +++ b/src/rm/RequestManager.cc @@ -293,7 +293,6 @@ void RequestManager::register_xml_methods() xmlrpc_c::methodPtr vm_deploy(new VirtualMachineDeploy()); xmlrpc_c::methodPtr vm_migrate(new VirtualMachineMigrate()); xmlrpc_c::methodPtr vm_action(new VirtualMachineAction()); - xmlrpc_c::methodPtr vm_savedisk(new VirtualMachineSaveDisk()); xmlrpc_c::methodPtr vm_monitoring(new VirtualMachineMonitoring()); xmlrpc_c::methodPtr vm_attach(new VirtualMachineAttach()); xmlrpc_c::methodPtr vm_detach(new VirtualMachineDetach()); @@ -303,6 +302,7 @@ void RequestManager::register_xml_methods() xmlrpc_c::methodPtr vm_snap_create(new VirtualMachineSnapshotCreate()); xmlrpc_c::methodPtr vm_snap_revert(new VirtualMachineSnapshotRevert()); xmlrpc_c::methodPtr vm_snap_delete(new VirtualMachineSnapshotDelete()); + xmlrpc_c::methodPtr vm_dexport(new VirtualMachineDiskExport()); xmlrpc_c::methodPtr vm_dsnap_create(new VirtualMachineDiskSnapshotCreate()); xmlrpc_c::methodPtr vm_dsnap_revert(new VirtualMachineDiskSnapshotRevert()); xmlrpc_c::methodPtr vm_dsnap_delete(new VirtualMachineDiskSnapshotDelete()); @@ -448,7 +448,6 @@ void RequestManager::register_xml_methods() RequestManagerRegistry.addMethod("one.vm.deploy", vm_deploy); RequestManagerRegistry.addMethod("one.vm.action", vm_action); RequestManagerRegistry.addMethod("one.vm.migrate", vm_migrate); - RequestManagerRegistry.addMethod("one.vm.savedisk", vm_savedisk); RequestManagerRegistry.addMethod("one.vm.allocate", vm_allocate); RequestManagerRegistry.addMethod("one.vm.info", vm_info); RequestManagerRegistry.addMethod("one.vm.chown", vm_chown); @@ -464,6 +463,7 @@ void RequestManager::register_xml_methods() RequestManagerRegistry.addMethod("one.vm.snapshotcreate", vm_snap_create); RequestManagerRegistry.addMethod("one.vm.snapshotrevert", vm_snap_revert); RequestManagerRegistry.addMethod("one.vm.snapshotdelete", vm_snap_delete); + RequestManagerRegistry.addMethod("one.vm.diskexport", vm_dexport); RequestManagerRegistry.addMethod("one.vm.disksnapshotcreate", vm_dsnap_create); RequestManagerRegistry.addMethod("one.vm.disksnapshotrevert", vm_dsnap_revert); RequestManagerRegistry.addMethod("one.vm.disksnapshotdelete", vm_dsnap_delete); diff --git a/src/rm/RequestManagerVirtualMachine.cc b/src/rm/RequestManagerVirtualMachine.cc index c812424844..6bb1d5cc3b 100644 --- a/src/rm/RequestManagerVirtualMachine.cc +++ b/src/rm/RequestManagerVirtualMachine.cc @@ -1176,7 +1176,7 @@ void VirtualMachineMigrate::request_execute(xmlrpc_c::paramList const& paramList /* -------------------------------------------------------------------------- */ /* -------------------------------------------------------------------------- */ -void VirtualMachineSaveDisk::request_execute(xmlrpc_c::paramList const& paramList, +void VirtualMachineDiskExport::request_execute(xmlrpc_c::paramList const& paramList, RequestAttributes& att) { Nebula& nd = Nebula::instance(); @@ -1398,6 +1398,8 @@ void VirtualMachineSaveDisk::request_execute(xmlrpc_c::paramList const& paramLis success_response(iid, att); + return; + error_state: vm->unlock(); diff --git a/src/sunstone/models/OpenNebulaJSON/VirtualMachineJSON.rb b/src/sunstone/models/OpenNebulaJSON/VirtualMachineJSON.rb index 987d780f78..b181f4ddd3 100644 --- a/src/sunstone/models/OpenNebulaJSON/VirtualMachineJSON.rb +++ b/src/sunstone/models/OpenNebulaJSON/VirtualMachineJSON.rb @@ -55,7 +55,6 @@ module OpenNebulaJSON when "suspend" then self.suspend when "reset" then self.reset when "saveas" then self.save_as(action_hash['params']) - when "disk_snapshot_cancel" then self.disk_snapshot_cancel(action_hash['params']) when "snapshot_create" then self.snapshot_create(action_hash['params']) when "snapshot_revert" then self.snapshot_revert(action_hash['params']) when "snapshot_delete" then self.snapshot_delete(action_hash['params']) @@ -105,14 +104,7 @@ module OpenNebulaJSON end def save_as(params=Hash.new) - clone = params['clonetemplate'] - clone = false if clone.nil? - - disk_snapshot(params['disk_id'].to_i, params['image_name'], params['type'], params['hot'], clone) - end - - def disk_snapshot_cancel(params=Hash.new) - super(params['disk_id'].to_i) + disk_export(params['disk_id'].to_i, params['image_name'], params['type']) end def snapshot_create(params=Hash.new) From 630e0360053de10ff4748089361f570ed354ad95 Mon Sep 17 00:00:00 2001 From: "Ruben S. Montero" Date: Wed, 10 Jun 2015 12:53:55 +0200 Subject: [PATCH 04/15] feature #3782: Removed _hot from saveas functions --- include/LifeCycleManager.h | 8 +++--- include/VirtualMachine.h | 25 ++++++++-------- src/image/ImageManagerDriver.cc | 2 +- src/lcm/LifeCycleActions.cc | 4 +-- src/lcm/LifeCycleManager.cc | 16 +++++------ src/lcm/LifeCycleStates.cc | 16 +++++------ src/tm/TransferManager.cc | 6 ++-- src/tm/TransferManagerDriver.cc | 4 +-- src/vm/VirtualMachine.cc | 51 ++++++++++++++++----------------- 9 files changed, 66 insertions(+), 66 deletions(-) diff --git a/include/LifeCycleManager.h b/include/LifeCycleManager.h index 24d12bf1dd..a98f925986 100644 --- a/include/LifeCycleManager.h +++ b/include/LifeCycleManager.h @@ -75,8 +75,8 @@ public: DETACH_NIC_FAILURE,/**< Sent by the VMM when a detach nic action fails */ CLEANUP_SUCCESS, /**< Sent by the VMM when a cleanup action succeeds */ CLEANUP_FAILURE, /**< Sent by the VMM when a cleanup action fails */ - SAVEAS_HOT_SUCCESS,/**< Sent by the VMM when hot saveas succeeds */ - SAVEAS_HOT_FAILURE,/**< Sent by the VMM when hot saveas fails */ + SAVEAS_SUCCESS, /**< Sent by the VMM when saveas succeeds */ + SAVEAS_FAILURE, /**< Sent by the VMM when saveas fails */ SNAPSHOT_CREATE_SUCCESS, /**< Sent by the VMM on snap. create success */ SNAPSHOT_CREATE_FAILURE, /**< Sent by the VMM on snap. create failure */ SNAPSHOT_REVERT_SUCCESS, /**< Sent by the VMM on snap. revert success */ @@ -252,9 +252,9 @@ private: void detach_failure_action(int vid); - void saveas_hot_success_action(int vid); + void saveas_success_action(int vid); - void saveas_hot_failure_action(int vid); + void saveas_failure_action(int vid); void attach_nic_success_action(int vid); diff --git a/include/VirtualMachine.h b/include/VirtualMachine.h index 3c3b08d352..b0b9701002 100644 --- a/include/VirtualMachine.h +++ b/include/VirtualMachine.h @@ -1280,6 +1280,14 @@ public: */ int set_saveas_disk(int disk_id, string& err_str); + /** + * Set export attributes for the disk + * @param disk_id Index of the disk to export + * @param source to save the disk + * @param img_id ID of the image this disk will be saved to + */ + int set_saveas_disk(int disk_id, const string& source, int img_id); + /** * Sets the corresponding state to export the disk. * @return 0 if the VM can be exported @@ -1299,26 +1307,19 @@ public: */ int clear_saveas_disk(); - /** - * Set the SAVE_AS attribute for the "disk_id"th disk. - * @param disk_id Index of the disk to save - * @param source to save the disk (SAVE_AS_SOURCE) - * @param img_id ID of the image this disk will be saved to (SAVE_AS). - */ - int save_disk_hot(int disk_id, - const string& source, - int img_id); /** * Get the original image id of the disk. It also checks that the disk can * be saved_as. * @param disk_id Index of the disk to save - * @param error_str describes the error + * @param source of the image to save the disk to + * @param image_id of the image to save the disk to + * @param tm_mad in use by the disk + * @param ds_id of the datastore in use by the disk * @return -1 if failure */ - int get_saveas_disk_hot(int& disk_id, string& source, int& image_id, + int get_saveas_disk(int& disk_id, string& source, int& image_id, string& tm_mad, string& ds_id); - // ------------------------------------------------------------------------ // Authorization related functions // ------------------------------------------------------------------------ diff --git a/src/image/ImageManagerDriver.cc b/src/image/ImageManagerDriver.cc index e97fb47889..d2cda36e9d 100644 --- a/src/image/ImageManagerDriver.cc +++ b/src/image/ImageManagerDriver.cc @@ -455,7 +455,7 @@ static int mkfs_action(istringstream& is, goto error_save_get; } - if ( vm->save_disk_hot(disk_id, source, id) == -1 ) + if ( vm->set_saveas_disk(disk_id, source, id) == -1 ) { goto error_save_state; } diff --git a/src/lcm/LifeCycleActions.cc b/src/lcm/LifeCycleActions.cc index 5599c8f4ce..81a3ec4e08 100644 --- a/src/lcm/LifeCycleActions.cc +++ b/src/lcm/LifeCycleActions.cc @@ -1129,11 +1129,11 @@ void LifeCycleManager::recover(VirtualMachine * vm, bool success) case VirtualMachine::HOTPLUG_SAVEAS_SUSPENDED: if (success) { - lcm_action = LifeCycleManager::SAVEAS_HOT_SUCCESS; + lcm_action = LifeCycleManager::SAVEAS_SUCCESS; } else { - lcm_action = LifeCycleManager::SAVEAS_HOT_FAILURE; + lcm_action = LifeCycleManager::SAVEAS_FAILURE; } break; diff --git a/src/lcm/LifeCycleManager.cc b/src/lcm/LifeCycleManager.cc index 84b61b5246..1f98cb806f 100644 --- a/src/lcm/LifeCycleManager.cc +++ b/src/lcm/LifeCycleManager.cc @@ -166,12 +166,12 @@ void LifeCycleManager::trigger(Actions action, int _vid) aname = "DETACH_FAILURE"; break; - case SAVEAS_HOT_SUCCESS: - aname = "SAVEAS_HOT_SUCCESS"; + case SAVEAS_SUCCESS: + aname = "SAVEAS_SUCCESS"; break; - case SAVEAS_HOT_FAILURE: - aname = "SAVEAS_HOT_FAILURE"; + case SAVEAS_FAILURE: + aname = "SAVEAS_FAILURE"; break; case ATTACH_NIC_SUCCESS: @@ -399,13 +399,13 @@ void LifeCycleManager::do_action(const string &action, void * arg) { detach_failure_action(vid); } - else if (action == "SAVEAS_HOT_SUCCESS") + else if (action == "SAVEAS_SUCCESS") { - saveas_hot_success_action(vid); + saveas_success_action(vid); } - else if (action == "SAVEAS_HOT_FAILURE") + else if (action == "SAVEAS_FAILURE") { - saveas_hot_failure_action(vid); + saveas_failure_action(vid); } else if (action == "ATTACH_NIC_SUCCESS") { diff --git a/src/lcm/LifeCycleStates.cc b/src/lcm/LifeCycleStates.cc index 7c350351d2..2a36ead8f8 100644 --- a/src/lcm/LifeCycleStates.cc +++ b/src/lcm/LifeCycleStates.cc @@ -1604,7 +1604,7 @@ void LifeCycleManager::detach_nic_failure_action(int vid) /* -------------------------------------------------------------------------- */ /* -------------------------------------------------------------------------- */ -void LifeCycleManager::saveas_hot_success_action(int vid) +void LifeCycleManager::saveas_success_action(int vid) { int image_id; int disk_id; @@ -1619,7 +1619,7 @@ void LifeCycleManager::saveas_hot_success_action(int vid) return; } - int rc = vm->get_saveas_disk_hot(disk_id, source, image_id, tm_mad, ds_id); + int rc = vm->get_saveas_disk(disk_id, source, image_id, tm_mad, ds_id); vm->clear_saveas_disk(); @@ -1638,14 +1638,14 @@ void LifeCycleManager::saveas_hot_success_action(int vid) vm->unlock(); - if ( rc != 0 ) + if (rc != 0) { return; } Image * image = ipool->get(image_id, true); - if ( image == 0 ) + if (image == 0) { return; } @@ -1660,7 +1660,7 @@ void LifeCycleManager::saveas_hot_success_action(int vid) /* -------------------------------------------------------------------------- */ /* -------------------------------------------------------------------------- */ -void LifeCycleManager::saveas_hot_failure_action(int vid) +void LifeCycleManager::saveas_failure_action(int vid) { int image_id; int disk_id; @@ -1675,7 +1675,7 @@ void LifeCycleManager::saveas_hot_failure_action(int vid) return; } - int rc = vm->get_saveas_disk_hot(disk_id, source, image_id, tm_mad, ds_id); + int rc = vm->get_saveas_disk(disk_id, source, image_id, tm_mad, ds_id); vm->clear_saveas_disk(); @@ -1694,14 +1694,14 @@ void LifeCycleManager::saveas_hot_failure_action(int vid) vm->unlock(); - if ( rc != 0 ) + if (rc != 0) { return; } Image * image = ipool->get(image_id, true); - if ( image == 0 ) + if (image == 0) { return; } diff --git a/src/tm/TransferManager.cc b/src/tm/TransferManager.cc index e670c82ce5..a3dcbaea7d 100644 --- a/src/tm/TransferManager.cc +++ b/src/tm/TransferManager.cc @@ -2084,9 +2084,9 @@ void TransferManager::saveas_hot_action(int vid) goto error_common; } - if (vm->get_saveas_disk_hot(disk_id, source, image_id, tm_mad, ds_id) != 0) + if (vm->get_saveas_disk(disk_id, source, image_id, tm_mad, ds_id) != 0) { - vm->log("TM", Log::ERROR,"Could not get disk information to saveas it"); + vm->log("TM", Log::ERROR,"Could not get disk information to export it"); goto error_common; } @@ -2135,7 +2135,7 @@ error_file: error_common: vm->log("TM", Log::ERROR, os); - (nd.get_lcm())->trigger(LifeCycleManager::SAVEAS_HOT_FAILURE, vid); + (nd.get_lcm())->trigger(LifeCycleManager::SAVEAS_FAILURE, vid); vm->unlock(); return; diff --git a/src/tm/TransferManagerDriver.cc b/src/tm/TransferManagerDriver.cc index d7c6b16b19..79ae4a7556 100644 --- a/src/tm/TransferManagerDriver.cc +++ b/src/tm/TransferManagerDriver.cc @@ -136,7 +136,7 @@ void TransferManagerDriver::protocol(const string& message) const case VirtualMachine::HOTPLUG_SAVEAS: case VirtualMachine::HOTPLUG_SAVEAS_POWEROFF: case VirtualMachine::HOTPLUG_SAVEAS_SUSPENDED: - lcm_action = LifeCycleManager::SAVEAS_HOT_SUCCESS; + lcm_action = LifeCycleManager::SAVEAS_SUCCESS; break; case VirtualMachine::HOTPLUG_PROLOG_POWEROFF: @@ -197,7 +197,7 @@ void TransferManagerDriver::protocol(const string& message) const case VirtualMachine::HOTPLUG_SAVEAS: case VirtualMachine::HOTPLUG_SAVEAS_POWEROFF: case VirtualMachine::HOTPLUG_SAVEAS_SUSPENDED: - lcm_action = LifeCycleManager::SAVEAS_HOT_FAILURE; + lcm_action = LifeCycleManager::SAVEAS_FAILURE; break; case VirtualMachine::HOTPLUG_PROLOG_POWEROFF: diff --git a/src/vm/VirtualMachine.cc b/src/vm/VirtualMachine.cc index 6c08419a36..848232838c 100644 --- a/src/vm/VirtualMachine.cc +++ b/src/vm/VirtualMachine.cc @@ -3242,6 +3242,30 @@ int VirtualMachine::set_saveas_disk(int disk_id, string& err_str) /* -------------------------------------------------------------------------- */ /* -------------------------------------------------------------------------- */ +int VirtualMachine::set_saveas_disk(int disk_id, const string& source, int iid) +{ + if (lcm_state != HOTPLUG_SAVEAS && lcm_state != HOTPLUG_SAVEAS_SUSPENDED + && lcm_state != HOTPLUG_SAVEAS_POWEROFF ) + { + return -1; + } + + VectorAttribute * disk = get_disk(disk_id); + + if ( disk == 0 ) + { + return -1; + } + + disk->replace("HOTPLUG_SAVE_AS", iid); + disk->replace("HOTPLUG_SAVE_AS_SOURCE", source); + + return 0; +} + +/* -------------------------------------------------------------------------- */ +/* -------------------------------------------------------------------------- */ + int VirtualMachine::set_saveas_state() { switch (state) @@ -3339,36 +3363,11 @@ int VirtualMachine::clear_saveas_disk() return -1; } -/* -------------------------------------------------------------------------- */ -/* -------------------------------------------------------------------------- */ - -int VirtualMachine::save_disk_hot(int disk_id, - const string& source, - int img_id) -{ - if (lcm_state != HOTPLUG_SAVEAS && lcm_state != HOTPLUG_SAVEAS_SUSPENDED - && lcm_state != HOTPLUG_SAVEAS_POWEROFF ) - { - return -1; - } - - VectorAttribute * disk = get_disk(disk_id); - - if ( disk == 0 ) - { - return -1; - } - - disk->replace("HOTPLUG_SAVE_AS", img_id); - disk->replace("HOTPLUG_SAVE_AS_SOURCE", source); - - return 0; -} /* -------------------------------------------------------------------------- */ /* -------------------------------------------------------------------------- */ -int VirtualMachine::get_saveas_disk_hot(int& disk_id, string& source, +int VirtualMachine::get_saveas_disk(int& disk_id, string& source, int& image_id, string& tm_mad, string& ds_id) { vector disks; From 80c06dca381f616b3776c0db9cd6148ee7c25977 Mon Sep 17 00:00:00 2001 From: "Ruben S. Montero" Date: Wed, 10 Jun 2015 19:56:35 +0200 Subject: [PATCH 05/15] feature #3782: renamed method to disksaveas, cli and Ruby OCA. Added snap id to save as disks --- include/Image.h | 2 +- include/ImageTemplate.h | 4 +- include/RequestManagerVirtualMachine.h | 12 ++-- include/VirtualMachine.h | 23 ++++---- src/cli/one_helper/onevm_helper.rb | 7 +-- src/cli/onevm | 8 +-- src/cloud/ec2/lib/EC2QueryServer.rb | 2 +- src/cloud/ec2/lib/ebs.rb | 2 +- src/image/ImageManagerDriver.cc | 4 +- src/lcm/LifeCycleStates.cc | 10 ++-- src/oca/ruby/opennebula/virtual_machine.rb | 15 +++-- src/rm/RequestManager.cc | 4 +- src/rm/RequestManagerVirtualMachine.cc | 13 +++-- .../OpenNebulaJSON/VirtualMachineJSON.rb | 2 +- src/tm/TransferManager.cc | 12 ++-- src/vm/VirtualMachine.cc | 56 ++++++++++++++----- 16 files changed, 104 insertions(+), 72 deletions(-) diff --git a/include/Image.h b/include/Image.h index ee1be2757c..b12f7eac9e 100644 --- a/include/Image.h +++ b/include/Image.h @@ -354,7 +354,7 @@ public: */ bool is_saving() { - return (static_cast(obj_template))->is_saving_hot(); + return (static_cast(obj_template))->is_saving(); } /** diff --git a/include/ImageTemplate.h b/include/ImageTemplate.h index 45348abe1b..6391161c67 100644 --- a/include/ImageTemplate.h +++ b/include/ImageTemplate.h @@ -59,7 +59,7 @@ public: Template::remove_all_except_restricted(restricted_attributes); }; - bool is_saving_hot() + bool is_saving() { bool save_as_hot; @@ -68,7 +68,7 @@ public: return save_as_hot; } - void set_saving_hot() + void set_saving() { replace("SAVE_AS_HOT", "YES"); } diff --git a/include/RequestManagerVirtualMachine.h b/include/RequestManagerVirtualMachine.h index 33f606d50e..44c6b974e6 100644 --- a/include/RequestManagerVirtualMachine.h +++ b/include/RequestManagerVirtualMachine.h @@ -170,15 +170,15 @@ public: /* ------------------------------------------------------------------------- */ /* ------------------------------------------------------------------------- */ -class VirtualMachineDiskExport : public RequestManagerVirtualMachine +class VirtualMachineDiskSaveas : public RequestManagerVirtualMachine { public: - VirtualMachineDiskExport(): - RequestManagerVirtualMachine("VirtualMachineDiskExport", - "Exports a disk from virtual machine as a new image", - "A:siiss"){}; + VirtualMachineDiskSaveas(): + RequestManagerVirtualMachine("VirtualMachineDiskSaveas", + "Save a disk from virtual machine as a new image", + "A:siissi"){}; - ~VirtualMachineDiskExport(){}; + ~VirtualMachineDiskSaveas(){}; void request_execute(xmlrpc_c::paramList const& _paramList, RequestAttributes& att); diff --git a/include/VirtualMachine.h b/include/VirtualMachine.h index b0b9701002..2ca85bfa57 100644 --- a/include/VirtualMachine.h +++ b/include/VirtualMachine.h @@ -1270,38 +1270,39 @@ public: int generate_context(string &files, int &disk_id, string& token_password); // ------------------------------------------------------------------------- - // Export Disk related functions (save_as hot) + // "Save as" Disk related functions (save_as hot) // ------------------------------------------------------------------------- /** - * Mark the disk that is going to be exported (saved_as) + * Mark the disk that is going to be "save as" * @param disk_id of the VM + * @param snap_id of the disk to save, -1 to select the active snapshot * @param err_str describing the error * @return -1 if the image cannot saveas or image_id of current disk */ - int set_saveas_disk(int disk_id, string& err_str); + int set_saveas_disk(int disk_id, int snap_id, string& err_str); /** - * Set export attributes for the disk - * @param disk_id Index of the disk to export + * Set save attributes for the disk + * @param disk_id Index of the disk to save * @param source to save the disk * @param img_id ID of the image this disk will be saved to */ int set_saveas_disk(int disk_id, const string& source, int img_id); /** - * Sets the corresponding state to export the disk. - * @return 0 if the VM can be exported + * Sets the corresponding state to save the disk. + * @return 0 if the VM can be saved */ int set_saveas_state(); /** - * Clears the export state, moving the VM to the original state. - * @return 0 if the VM was in an export state + * Clears the save state, moving the VM to the original state. + * @return 0 if the VM was in an saveas state */ int clear_saveas_state(); /** - * Clears the export attributes of the disk being saved as + * Clears the SAVE_AS_* attributes of the disk being saved as * @return the ID of the image this disk will be saved to or -1 if it * is not found. */ @@ -1318,7 +1319,7 @@ public: * @return -1 if failure */ int get_saveas_disk(int& disk_id, string& source, int& image_id, - string& tm_mad, string& ds_id); + string& snap_id, string& tm_mad, string& ds_id); // ------------------------------------------------------------------------ // Authorization related functions diff --git a/src/cli/one_helper/onevm_helper.rb b/src/cli/one_helper/onevm_helper.rb index b2d080305b..22e4d6e3da 100644 --- a/src/cli/one_helper/onevm_helper.rb +++ b/src/cli/one_helper/onevm_helper.rb @@ -601,13 +601,8 @@ class OneVMHelper < OpenNebulaHelper::OneHelper d["CLONE"] end - column :"SAVE_AS", "", :size=>7 do |d| - d["SAVE_AS"] || "-" - end - - default :ID, :TARGET, :IMAGE, :TYPE, - :SAVE, :SAVE_AS + :SAVE end.show(vm_disks, {}) while vm.has_elements?("/VM/TEMPLATE/DISK") diff --git a/src/cli/onevm b/src/cli/onevm index e97023ea3b..42f0d093ae 100755 --- a/src/cli/onevm +++ b/src/cli/onevm @@ -298,15 +298,15 @@ cmd=CommandParser::CmdParser.new(ARGV) do end end - disk_export_desc = <<-EOT.unindent - Exports the specified VM disk to a new Image. The Image is + disk_saveas_desc = <<-EOT.unindent + Saves the specified VM disk as a new Image. The Image is created immediately, and the contents of the VM disk will be saved to it. States: ANY EOT - command :"disk-export", disk_export_desc, :vmid, :diskid, :img_name, + command :"disk-saveas", disk_saveas_desc, :vmid, :diskid, :img_name, :options=>[TYPE] do disk_id = args[1].to_i image_name = args[2] @@ -316,7 +316,7 @@ cmd=CommandParser::CmdParser.new(ARGV) do "the image #{image_name}" helper.perform_action(args[0],options,verbose) do |vm| - res = vm.disk_export(disk_id, image_name, image_type) + res = vm.disk_saveas(disk_id, image_name, image_type,-1) if !OpenNebula.is_error?(res) puts "Image ID: #{res}" diff --git a/src/cloud/ec2/lib/EC2QueryServer.rb b/src/cloud/ec2/lib/EC2QueryServer.rb index 5381e4443c..37b58bd15a 100644 --- a/src/cloud/ec2/lib/EC2QueryServer.rb +++ b/src/cloud/ec2/lib/EC2QueryServer.rb @@ -218,7 +218,7 @@ class EC2QueryServer < CloudServer return rc end - image_id = vm.disk_export(1, + image_id = vm.disk_saveas(1, params["Name"], OpenNebula::Image::IMAGE_TYPES[0]) diff --git a/src/cloud/ec2/lib/ebs.rb b/src/cloud/ec2/lib/ebs.rb index 9f6807ff87..eff3b3575e 100644 --- a/src/cloud/ec2/lib/ebs.rb +++ b/src/cloud/ec2/lib/ebs.rb @@ -302,7 +302,7 @@ module EBS disk_id = vm["TEMPLATE/DISK[IMAGE_ID=#{image_id}]/DISK_ID"] if !disk_id.nil? - snapshot_id = vm.disk_export(disk_id.to_i, + snapshot_id = vm.disk_saveas(disk_id.to_i, params["Description"]||ImageEC2.generate_uuid, OpenNebula::Image::IMAGE_TYPES[image["TYPE"].to_i]) diff --git a/src/image/ImageManagerDriver.cc b/src/image/ImageManagerDriver.cc index d2cda36e9d..6bb6fa1aac 100644 --- a/src/image/ImageManagerDriver.cc +++ b/src/image/ImageManagerDriver.cc @@ -473,12 +473,12 @@ error_img: goto error; error_save_get: - oss << "Image created for SAVE_AS, but the associated VM does not exist."; + oss << "Image created to save as a disk but VM does not exist."; goto error_save; error_save_state: vm->unlock(); - oss << "Image created for SAVE_AS, but VM is no longer running"; + oss << "Image created to save as disk but VM is no longer running"; error_save: image = ipool->get(id, true); diff --git a/src/lcm/LifeCycleStates.cc b/src/lcm/LifeCycleStates.cc index 2a36ead8f8..76954ab173 100644 --- a/src/lcm/LifeCycleStates.cc +++ b/src/lcm/LifeCycleStates.cc @@ -1609,8 +1609,9 @@ void LifeCycleManager::saveas_success_action(int vid) int image_id; int disk_id; string tm_mad; + string snap; string ds_id; - string source; + string src; VirtualMachine * vm = vmpool->get(vid,true); @@ -1619,7 +1620,7 @@ void LifeCycleManager::saveas_success_action(int vid) return; } - int rc = vm->get_saveas_disk(disk_id, source, image_id, tm_mad, ds_id); + int rc = vm->get_saveas_disk(disk_id, src, image_id, snap, tm_mad, ds_id); vm->clear_saveas_disk(); @@ -1665,8 +1666,9 @@ void LifeCycleManager::saveas_failure_action(int vid) int image_id; int disk_id; string tm_mad; + string snap; string ds_id; - string source; + string src; VirtualMachine * vm = vmpool->get(vid,true); @@ -1675,7 +1677,7 @@ void LifeCycleManager::saveas_failure_action(int vid) return; } - int rc = vm->get_saveas_disk(disk_id, source, image_id, tm_mad, ds_id); + int rc = vm->get_saveas_disk(disk_id, src, image_id, snap, tm_mad, ds_id); vm->clear_saveas_disk(); diff --git a/src/oca/ruby/opennebula/virtual_machine.rb b/src/oca/ruby/opennebula/virtual_machine.rb index 71dfda1ca7..cb686f1f4e 100644 --- a/src/oca/ruby/opennebula/virtual_machine.rb +++ b/src/oca/ruby/opennebula/virtual_machine.rb @@ -43,7 +43,7 @@ module OpenNebula :attachnic => "vm.attachnic", :detachnic => "vm.detachnic", :recover => "vm.recover", - :diskexport => "vm.diskexport", + :disksaveas => "vm.disksaveas", :disksnapshotcreate => "vm.disksnapshotcreate", :disksnapshotrevert => "vm.disksnapshotrevert", :disksnapshotdelete => "vm.disksnapshotdelete" @@ -459,7 +459,7 @@ module OpenNebula migrate(host_id, true, enforce) end - # Set the specified vm's disk to be saved in a new image + # Set the specified vm's disk to be saved as a new image # when the VirtualMachine shutdowns # # @param disk_id [Integer] ID of the disk to be saved @@ -467,17 +467,20 @@ module OpenNebula # disk will be saved # @param image_type [String] Type of the new image. Set to empty string # to use the default type + # @param snap_id [Integer] ID of the snapshot to save, -1 to use the + # current disk image state # # @return [Integer, OpenNebula::Error] the new Image ID in case of # success, error otherwise - def disk_export(disk_id, image_name, image_type="") + def disk_saveas(disk_id, image_name, image_type="", snap_id=-1) return Error.new('ID not defined') if !@pe_id - rc = @client.call(VM_METHODS[:diskexport], + rc = @client.call(VM_METHODS[:disksaveas], @pe_id, disk_id, image_name, - image_type) + image_type, + snap_id) return rc end @@ -767,7 +770,7 @@ module OpenNebula image_id = disk["IMAGE_ID"] if !image_id.nil? && !image_id.empty? - rc = disk_export(disk_id.to_i,"#{name}-disk-#{disk_id}","") + rc = disk_saveas(disk_id.to_i,"#{name}-disk-#{disk_id}","",-1) return rc if OpenNebula.is_error?(rc) diff --git a/src/rm/RequestManager.cc b/src/rm/RequestManager.cc index 72a29c3d91..78ed77a113 100644 --- a/src/rm/RequestManager.cc +++ b/src/rm/RequestManager.cc @@ -302,7 +302,7 @@ void RequestManager::register_xml_methods() xmlrpc_c::methodPtr vm_snap_create(new VirtualMachineSnapshotCreate()); xmlrpc_c::methodPtr vm_snap_revert(new VirtualMachineSnapshotRevert()); xmlrpc_c::methodPtr vm_snap_delete(new VirtualMachineSnapshotDelete()); - xmlrpc_c::methodPtr vm_dexport(new VirtualMachineDiskExport()); + xmlrpc_c::methodPtr vm_dsaveas(new VirtualMachineDiskSaveas()); xmlrpc_c::methodPtr vm_dsnap_create(new VirtualMachineDiskSnapshotCreate()); xmlrpc_c::methodPtr vm_dsnap_revert(new VirtualMachineDiskSnapshotRevert()); xmlrpc_c::methodPtr vm_dsnap_delete(new VirtualMachineDiskSnapshotDelete()); @@ -463,7 +463,7 @@ void RequestManager::register_xml_methods() RequestManagerRegistry.addMethod("one.vm.snapshotcreate", vm_snap_create); RequestManagerRegistry.addMethod("one.vm.snapshotrevert", vm_snap_revert); RequestManagerRegistry.addMethod("one.vm.snapshotdelete", vm_snap_delete); - RequestManagerRegistry.addMethod("one.vm.diskexport", vm_dexport); + RequestManagerRegistry.addMethod("one.vm.disksaveas", vm_dsaveas); RequestManagerRegistry.addMethod("one.vm.disksnapshotcreate", vm_dsnap_create); RequestManagerRegistry.addMethod("one.vm.disksnapshotrevert", vm_dsnap_revert); RequestManagerRegistry.addMethod("one.vm.disksnapshotdelete", vm_dsnap_delete); diff --git a/src/rm/RequestManagerVirtualMachine.cc b/src/rm/RequestManagerVirtualMachine.cc index 6bb1d5cc3b..a2390fd4dc 100644 --- a/src/rm/RequestManagerVirtualMachine.cc +++ b/src/rm/RequestManagerVirtualMachine.cc @@ -1176,8 +1176,8 @@ void VirtualMachineMigrate::request_execute(xmlrpc_c::paramList const& paramList /* -------------------------------------------------------------------------- */ /* -------------------------------------------------------------------------- */ -void VirtualMachineDiskExport::request_execute(xmlrpc_c::paramList const& paramList, - RequestAttributes& att) +void VirtualMachineDiskSaveas::request_execute( + xmlrpc_c::paramList const& paramList, RequestAttributes& att) { Nebula& nd = Nebula::instance(); @@ -1188,6 +1188,7 @@ void VirtualMachineDiskExport::request_execute(xmlrpc_c::paramList const& paramL int disk_id = xmlrpc_c::value_int(paramList.getInt(2)); string img_name = xmlrpc_c::value_string(paramList.getString(3)); string img_type = xmlrpc_c::value_string(paramList.getString(4)); + int snap_id = xmlrpc_c::value_int(paramList.getInt(5)); VirtualMachinePool * vmpool = static_cast(pool); @@ -1224,7 +1225,7 @@ void VirtualMachineDiskExport::request_execute(xmlrpc_c::paramList const& paramL string error; // ------------------------------------------------------------------------- - // Prepare and check the VM/DISK to be export + // Prepare and check the VM/DISK to be saved as // ------------------------------------------------------------------------- if ((vm = get_vm(id, att)) == 0) { @@ -1236,7 +1237,7 @@ void VirtualMachineDiskExport::request_execute(xmlrpc_c::paramList const& paramL goto error_state; } - iid_orig = vm->set_saveas_disk(disk_id, error); + iid_orig = vm->set_saveas_disk(disk_id, snap_id, error); if (iid_orig == -1) { @@ -1317,7 +1318,7 @@ void VirtualMachineDiskExport::request_execute(xmlrpc_c::paramList const& paramL itemplate->add("SAVED_IMAGE_ID",iid_orig); itemplate->add("SAVED_DISK_ID",disk_id); itemplate->add("SAVED_VM_ID", id); - itemplate->set_saving_hot(); + itemplate->set_saving(); if (img_type.empty()) { @@ -1404,7 +1405,7 @@ error_state: vm->unlock(); failure_response(INTERNAL,request_error("VM has to be RUNNING, POWEROFF or " - "SUSPENDED to export disks.",""), att); + "SUSPENDED to save disks.",""), att); return; error_disk: diff --git a/src/sunstone/models/OpenNebulaJSON/VirtualMachineJSON.rb b/src/sunstone/models/OpenNebulaJSON/VirtualMachineJSON.rb index b181f4ddd3..295b10e1ca 100644 --- a/src/sunstone/models/OpenNebulaJSON/VirtualMachineJSON.rb +++ b/src/sunstone/models/OpenNebulaJSON/VirtualMachineJSON.rb @@ -104,7 +104,7 @@ module OpenNebulaJSON end def save_as(params=Hash.new) - disk_export(params['disk_id'].to_i, params['image_name'], params['type']) + disk_saveas(params['disk_id'].to_i, params['image_name'], params['type']) end def snapshot_create(params=Hash.new) diff --git a/src/tm/TransferManager.cc b/src/tm/TransferManager.cc index a3dcbaea7d..80f479fbc1 100644 --- a/src/tm/TransferManager.cc +++ b/src/tm/TransferManager.cc @@ -2053,7 +2053,8 @@ void TransferManager::saveas_hot_action(int vid) { int disk_id; int image_id; - string source; + string src; + string snap_id; string tm_mad; string ds_id; @@ -2084,7 +2085,7 @@ void TransferManager::saveas_hot_action(int vid) goto error_common; } - if (vm->get_saveas_disk(disk_id, source, image_id, tm_mad, ds_id) != 0) + if (vm->get_saveas_disk(disk_id, src, image_id, snap_id, tm_mad, ds_id)!= 0) { vm->log("TM", Log::ERROR,"Could not get disk information to export it"); goto error_common; @@ -2097,7 +2098,7 @@ void TransferManager::saveas_hot_action(int vid) goto error_driver; } - xfr_name = vm->get_transfer_file() + ".saveas_hot"; + xfr_name = vm->get_transfer_file() + ".disk_saveas"; xfr.open(xfr_name.c_str(),ios::out | ios::trunc); if (xfr.fail() == true) @@ -2105,12 +2106,13 @@ void TransferManager::saveas_hot_action(int vid) goto error_file; } - //MVDS tm_mad hostname:remote_system_dir/disk.0 vmid dsid + //MVDS tm_mad hostname:remote_system_dir/disk.0 source snapid vmid dsid xfr << "CPDS " << tm_mad << " " << vm->get_hostname() << ":" << vm->get_remote_system_dir() << "/disk." << disk_id << " " - << source << " " + << src << " " + << snap_id << " " << vm->get_oid() << " " << ds_id << endl; diff --git a/src/vm/VirtualMachine.cc b/src/vm/VirtualMachine.cc index 848232838c..884600358d 100644 --- a/src/vm/VirtualMachine.cc +++ b/src/vm/VirtualMachine.cc @@ -2530,7 +2530,6 @@ int VirtualMachine::set_attach_nic(int nic_id) void VirtualMachine::release_disk_images() { int iid; - int save_as_id; int num_disks; int did = -1; @@ -2572,12 +2571,6 @@ void VirtualMachine::release_disk_images() imagem->release_image(oid, iid, img_error); } - - if ( disk->vector_value("SAVE_AS", save_as_id) == 0 ) - { - imagem->release_image(oid, save_as_id, img_error); - } - } } @@ -3216,25 +3209,49 @@ const VectorAttribute* VirtualMachine::get_disk(int disk_id) const /* -------------------------------------------------------------------------- */ /* -------------------------------------------------------------------------- */ -int VirtualMachine::set_saveas_disk(int disk_id, string& err_str) +int VirtualMachine::set_saveas_disk(int disk_id, int snap_id, string& err_str) { int iid = -1; VectorAttribute * disk = get_disk(disk_id); - if ( disk == 0 ) + if (disk == 0) { err_str = "DISK does not exist."; return -1; } - if ( disk->vector_value("IMAGE_ID", iid) != 0 ) + if (disk->vector_value("IMAGE_ID", iid) != 0) { err_str = "DISK does not have a valid IMAGE_ID."; return -1; } + const Snapshots * snaps = get_disk_snapshots(disk_id, err_str); + + if (snaps == 0) + { + if (snap_id != -1) + { + err_str = "Snapshot does not exists."; + return -1; + } + } + else + { + if (snap_id == -1) + { + snap_id = snaps->get_active_id(); + } + else if (!snaps->exists(snap_id)) + { + err_str = "Snapshot does not exists."; + return -1; + } + } + disk->replace("HOTPLUG_SAVE_AS_ACTIVE", "YES"); + disk->replace("HOTPLUG_SAVE_AS_SNAPSHOT_ID", snap_id); return iid; } @@ -3268,6 +3285,8 @@ int VirtualMachine::set_saveas_disk(int disk_id, const string& source, int iid) int VirtualMachine::set_saveas_state() { + string s; + switch (state) { case ACTIVE: @@ -3277,22 +3296,24 @@ int VirtualMachine::set_saveas_state() } lcm_state = HOTPLUG_SAVEAS; - break; + break; case POWEROFF: state = ACTIVE; lcm_state = HOTPLUG_SAVEAS_POWEROFF; - break; + break; case SUSPENDED: state = ACTIVE; lcm_state = HOTPLUG_SAVEAS_SUSPENDED; - break; + break; default: return -1; } + log("VM", Log::INFO, "New state is " + lcm_state_to_str(s,lcm_state)); + return 0; } @@ -3301,20 +3322,25 @@ int VirtualMachine::set_saveas_state() int VirtualMachine::clear_saveas_state() { + string s; + switch (lcm_state) { case HOTPLUG_SAVEAS: lcm_state = RUNNING; + log("VM", Log::INFO, "New state is "+lcm_state_to_str(s,lcm_state)); break; case HOTPLUG_SAVEAS_POWEROFF: state = POWEROFF; lcm_state = LCM_INIT; + log("VM", Log::INFO, "New state is " + vm_state_to_str(s,state)); break; case HOTPLUG_SAVEAS_SUSPENDED: state = SUSPENDED; lcm_state = LCM_INIT; + log("VM", Log::INFO, "New state is " + vm_state_to_str(s,state)); break; default: @@ -3355,6 +3381,7 @@ int VirtualMachine::clear_saveas_disk() disk->remove("HOTPLUG_SAVE_AS_ACTIVE"); disk->remove("HOTPLUG_SAVE_AS"); disk->remove("HOTPLUG_SAVE_AS_SOURCE"); + disk->remove("HOTPLUG_SAVE_AS_SNAPSHOT_ID"); return image_id; } @@ -3368,7 +3395,7 @@ int VirtualMachine::clear_saveas_disk() /* -------------------------------------------------------------------------- */ int VirtualMachine::get_saveas_disk(int& disk_id, string& source, - int& image_id, string& tm_mad, string& ds_id) + int& image_id, string& snap_id, string& tm_mad, string& ds_id) { vector disks; VectorAttribute * disk; @@ -3391,6 +3418,7 @@ int VirtualMachine::get_saveas_disk(int& disk_id, string& source, { rc = disk->vector_value("HOTPLUG_SAVE_AS_SOURCE", source); rc += disk->vector_value("HOTPLUG_SAVE_AS", image_id); + rc += disk->vector_value("HOTPLUG_SAVE_AS_SNAPSHOT_ID", snap_id); rc += disk->vector_value("DISK_ID", disk_id); rc += disk->vector_value("DATASTORE_ID", ds_id); rc += disk->vector_value("TM_MAD", tm_mad); From 943e0e5292d439fbc29ad3addb7e185d93862fc9 Mon Sep 17 00:00:00 2001 From: Javi Fontan Date: Wed, 10 Jun 2015 18:44:03 -0400 Subject: [PATCH 06/15] feature #3782: add qcow2 tm/snap_{create,revert} --- src/tm_mad/qcow2/snap_create | 75 +++++++++++++++++++++++++++++++++++- src/tm_mad/qcow2/snap_revert | 50 +++++++++++++++++++++++- 2 files changed, 123 insertions(+), 2 deletions(-) mode change 120000 => 100755 src/tm_mad/qcow2/snap_create mode change 120000 => 100755 src/tm_mad/qcow2/snap_revert diff --git a/src/tm_mad/qcow2/snap_create b/src/tm_mad/qcow2/snap_create deleted file mode 120000 index 9c454e8cd4..0000000000 --- a/src/tm_mad/qcow2/snap_create +++ /dev/null @@ -1 +0,0 @@ -../common/not_supported.sh \ No newline at end of file diff --git a/src/tm_mad/qcow2/snap_create b/src/tm_mad/qcow2/snap_create new file mode 100755 index 0000000000..f91356d7d1 --- /dev/null +++ b/src/tm_mad/qcow2/snap_create @@ -0,0 +1,74 @@ +#!/bin/bash -x + +# -------------------------------------------------------------------------- # +# Copyright 2002-2015, OpenNebula Project (OpenNebula.org), C12G Labs # +# # +# 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. # +#--------------------------------------------------------------------------- # + +# snap_create host:parent_image snap_id vmid ds_id + +SRC=$1 +SNAP_ID=$2 +VMID=$3 +DSID=$4 + +if [ -z "${ONE_LOCATION}" ]; then + TMCOMMON=/var/lib/one/remotes/tm/tm_common.sh + DATASTORES=/var/lib/one/datastores +else + TMCOMMON=$ONE_LOCATION/var/remotes/tm/tm_common.sh + DATASTORES=$ONE_LOCATION/var/datastores +fi + +. $TMCOMMON + +SRC_PATH=`arg_path $SRC` + +SYSTEM_DS_PATH=$(dirname ${SRC_PATH}) + +DISK_ID=$(basename ${SRC} | cut -d. -f2) +DISK_PATH="${SYSTEM_DS_PATH}/disk.${DISK_ID}" +SNAP_DIR="${DISK_PATH}.snap" +SNAP_PATH="${SNAP_DIR}/${SNAP_ID}" +SNAP_PATH_RELATIVE=$(basename ${SNAP_PATH}) +CURRENT_PATH=${DISK_PATH} + +if [ ! -d ${SNAP_PATH} ]; then + mkdir ${SNAP_DIR} +fi + +# Move save current snapshot and create a new one. The snapshot uses +# absolute path name as the qemu-img has problems with relative backing +# file paths and symlinks +mv ${CURRENT_PATH} ${SNAP_PATH} +qemu-img create -f qcow2 -b ${SNAP_PATH} ${CURRENT_PATH} + +# TODO: Check that the new snapshot can be created. Roll back in case +# of error + +# Convert backing file absolute path to relative path so it works outside +# the system directory. Do not do this for snapshot one as: +# * It could be a non backed file (persistent) +# * The backing file is in images directory, is not relative +if [ "$SNAP_ID" != "0" ]; then + BACKING_FILE=$(qemu-img info ${SNAP_PATH} | grep '^backing file:' | \ + cut -d: -f2 | sed 's/^ //') + + if [ -n "$BACKING_FILE" ]; then + RELATIVE_BACKING_FILE=$(basename ${BACKING_FILE}) + + qemu-img rebase -u -b ${RELATIVE_BACKING_FILE} ${SNAP_PATH} + fi +fi + diff --git a/src/tm_mad/qcow2/snap_revert b/src/tm_mad/qcow2/snap_revert deleted file mode 120000 index 9c454e8cd4..0000000000 --- a/src/tm_mad/qcow2/snap_revert +++ /dev/null @@ -1 +0,0 @@ -../common/not_supported.sh \ No newline at end of file diff --git a/src/tm_mad/qcow2/snap_revert b/src/tm_mad/qcow2/snap_revert new file mode 100755 index 0000000000..38ac9ae954 --- /dev/null +++ b/src/tm_mad/qcow2/snap_revert @@ -0,0 +1,49 @@ +#!/bin/bash + +# -------------------------------------------------------------------------- # +# Copyright 2002-2015, OpenNebula Project (OpenNebula.org), C12G Labs # +# # +# 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. # +#--------------------------------------------------------------------------- # + +# snap_create host:parent_image snap_id vmid ds_id + +SRC=$1 +SNAP_ID=$2 +VMID=$3 +DSID=$4 + +if [ -z "${ONE_LOCATION}" ]; then + TMCOMMON=/var/lib/one/remotes/tm/tm_common.sh + DATASTORES=/var/lib/one/datastores +else + TMCOMMON=$ONE_LOCATION/var/remotes/tm/tm_common.sh + DATASTORES=$ONE_LOCATION/var/datastores +fi + +. $TMCOMMON + +SRC_PATH=`arg_path $SRC` + +SYSTEM_DS_PATH=$(dirname ${SRC_PATH}) + +DISK_ID=$(basename ${SRC} | cut -d. -f2) +DISK_PATH="${SYSTEM_DS_PATH}/disk.${DISK_ID}" +SNAP_DIR="${DISK_PATH}.snap" +SNAP_PATH="${SNAP_DIR}/${SNAP_ID}" +SNAP_PATH_RELATIVE=$(basename ${SNAP_PATH}) +CURRENT_PATH=${DISK_PATH} + +rm ${CURRENT_PATH} +qemu-img create -f qcow2 -b ${SNAP_PATH} ${CURRENT_PATH} + From e5bcaea18de84b1aa4c4b626b0a962ada41e607d Mon Sep 17 00:00:00 2001 From: Javi Fontan Date: Wed, 10 Jun 2015 18:49:38 -0400 Subject: [PATCH 07/15] feature #3782: add qcow2 tm/snap_delete --- src/tm_mad/qcow2/snap_delete | 49 +++++++++++++++++++++++++++++++++++- 1 file changed, 48 insertions(+), 1 deletion(-) mode change 120000 => 100755 src/tm_mad/qcow2/snap_delete diff --git a/src/tm_mad/qcow2/snap_delete b/src/tm_mad/qcow2/snap_delete deleted file mode 120000 index 9c454e8cd4..0000000000 --- a/src/tm_mad/qcow2/snap_delete +++ /dev/null @@ -1 +0,0 @@ -../common/not_supported.sh \ No newline at end of file diff --git a/src/tm_mad/qcow2/snap_delete b/src/tm_mad/qcow2/snap_delete new file mode 100755 index 0000000000..d8d3c4d452 --- /dev/null +++ b/src/tm_mad/qcow2/snap_delete @@ -0,0 +1,48 @@ +#!/bin/bash + +# -------------------------------------------------------------------------- # +# Copyright 2002-2015, OpenNebula Project (OpenNebula.org), C12G Labs # +# # +# 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. # +#--------------------------------------------------------------------------- # + +# snap_delete host:parent_image snap_id vmid ds_id + +SRC=$1 +SNAP_ID=$2 +VMID=$3 +DSID=$4 + +if [ -z "${ONE_LOCATION}" ]; then + TMCOMMON=/var/lib/one/remotes/tm/tm_common.sh + DATASTORES=/var/lib/one/datastores +else + TMCOMMON=$ONE_LOCATION/var/remotes/tm/tm_common.sh + DATASTORES=$ONE_LOCATION/var/datastores +fi + +. $TMCOMMON + +SRC_PATH=`arg_path $SRC` + +SYSTEM_DS_PATH=$(dirname ${SRC_PATH}) + +DISK_ID=$(basename ${SRC} | cut -d. -f2) +DISK_PATH="${SYSTEM_DS_PATH}/disk.${DISK_ID}" +SNAP_DIR="${DISK_PATH}.snap" +SNAP_PATH="${SNAP_DIR}/${SNAP_ID}" +SNAP_PATH_RELATIVE=$(basename ${SNAP_PATH}) +CURRENT_PATH=${DISK_PATH} + +rm ${SNAP_PATH} + From 996ee89dc1fc3682cf81322f094b9c1790dba1fb Mon Sep 17 00:00:00 2001 From: Jaime Melis Date: Thu, 11 Jun 2015 18:09:41 +0200 Subject: [PATCH 08/15] feature #3782: allow disk-saveas operations on the currently running disk --- src/vm/VirtualMachine.cc | 18 +++--------------- 1 file changed, 3 insertions(+), 15 deletions(-) diff --git a/src/vm/VirtualMachine.cc b/src/vm/VirtualMachine.cc index 884600358d..a87af5db8f 100644 --- a/src/vm/VirtualMachine.cc +++ b/src/vm/VirtualMachine.cc @@ -3229,23 +3229,11 @@ int VirtualMachine::set_saveas_disk(int disk_id, int snap_id, string& err_str) const Snapshots * snaps = get_disk_snapshots(disk_id, err_str); - if (snaps == 0) + if (snap_id != -1) { - if (snap_id != -1) + if (snaps == 0 || !snaps->exists(snap_id)) { - err_str = "Snapshot does not exists."; - return -1; - } - } - else - { - if (snap_id == -1) - { - snap_id = snaps->get_active_id(); - } - else if (!snaps->exists(snap_id)) - { - err_str = "Snapshot does not exists."; + err_str = "Snapshot does not exist."; return -1; } } From ae33c915f2db946a69b9170d4fd01682024e8e69 Mon Sep 17 00:00:00 2001 From: Jaime Melis Date: Thu, 11 Jun 2015 18:10:23 +0200 Subject: [PATCH 09/15] feature #3782: Add snapshot id to the onevm disk-saveas command --- src/cli/onevm | 33 ++++++++++++++++++++++++++------- 1 file changed, 26 insertions(+), 7 deletions(-) diff --git a/src/cli/onevm b/src/cli/onevm index 42f0d093ae..7a8e380577 100755 --- a/src/cli/onevm +++ b/src/cli/onevm @@ -104,6 +104,14 @@ cmd=CommandParser::CmdParser.new(ARGV) do " the --retry option." } + SNAP={ + :name => "snapshot", + :short => "-s snapshot", + :large => "--snapshot snapshot", + :format => String, + :description => "ID of the Snapshot to save." + } + ######################################################################## # Global Options ######################################################################## @@ -307,16 +315,27 @@ cmd=CommandParser::CmdParser.new(ARGV) do EOT command :"disk-saveas", disk_saveas_desc, :vmid, :diskid, :img_name, - :options=>[TYPE] do - disk_id = args[1].to_i - image_name = args[2] - image_type = options[:type] || "" + :options=>[TYPE, SNAP] do - verbose = "disk #{disk_id} prepared to be saved in " << - "the image #{image_name}" + disk_id = args[1].to_i + image_name = args[2] + image_type = options[:type] || "" + snapshot_id = options[:snapshot] + + if snapshot_id.nil? || snapshot_id.empty? + snapshot_id = -1 + + verbose = "disk #{disk_id} prepared to be saved in " << + "the image #{image_name}" + else + snapshot_id = snapshot_id.to_i + + verbose = "disk #{disk_id} snapshot #{snapshot_id} prepared to " << + "be saved in the image #{image_name}" + end helper.perform_action(args[0],options,verbose) do |vm| - res = vm.disk_saveas(disk_id, image_name, image_type,-1) + res = vm.disk_saveas(disk_id, image_name, image_type, snapshot_id) if !OpenNebula.is_error?(res) puts "Image ID: #{res}" From d8c15a1394ebafcbe2f49884fa9f841931300bb4 Mon Sep 17 00:00:00 2001 From: Jaime Melis Date: Thu, 11 Jun 2015 18:11:08 +0200 Subject: [PATCH 10/15] feature #3782: Update ceph cpds and mvds scripts to handle snaps --- src/tm_mad/ceph/cpds | 14 +++++--- src/tm_mad/ceph/mvds | 81 -------------------------------------------- 2 files changed, 9 insertions(+), 86 deletions(-) diff --git a/src/tm_mad/ceph/cpds b/src/tm_mad/ceph/cpds index b4deda72b9..c194032aec 100755 --- a/src/tm_mad/ceph/cpds +++ b/src/tm_mad/ceph/cpds @@ -17,15 +17,18 @@ #--------------------------------------------------------------------------- # # mvds host:remote_system_ds/disk.i fe:SOURCE +# cpds host:remote_system_ds/disk.i fe:SOURCE snapid vmid dsid # - fe is the front-end hostname # - SOURCE is the path of the disk image in the form DS_BASE_PATH/disk # - host is the target host to deploy the VM # - remote_system_ds is the path for the system datastore in the host +# - snapid is the snapshot id. "-1" for none SRC=$1 DST=$2 -VM_ID=$3 -DS_ID=$4 +SNAP_ID=$3 +VM_ID=$4 +DS_ID=$5 if [ -z "${ONE_LOCATION}" ]; then TMCOMMON=/var/lib/one/remotes/tm/tm_common.sh @@ -43,13 +46,13 @@ source ${DRIVER_PATH}/../../datastore/ceph/ceph.conf #------------------------------------------------------------------------------- SRC_HOST=`arg_host $SRC` -SRC_PATH=`arg_path $SRC` +RBD_SRC=`arg_path $SRC` #------------------------------------------------------------------------------- # Get Image information #------------------------------------------------------------------------------- -DISK_ID=$(echo "$SRC_PATH" | $AWK -F. '{print $NF}') +DISK_ID=$(echo "$RBD_SRC" | $AWK -F. '{print $NF}') XPATH="${DRIVER_PATH}/../../datastore/xpath.rb --stdin" @@ -76,7 +79,7 @@ else RBD_DST="${RBD_SRC}-${VM_ID}-${DISK_ID}" fi -if [ -n "$SNAP_ID" ]; then +if [ "$SNAP_ID" != "-1" ]; then RBD_DST="${RBD_DST}-${SNAP_ID}@${SNAP_ID}" fi @@ -84,6 +87,7 @@ if [ -n "$CEPH_USER" ]; then RBD="$RBD --id ${CEPH_USER}" fi +echo "$RBD copy $RBD_DST $DST" > /tmp/k ssh_exec_and_log "$SRC_HOST" "$RBD copy $RBD_DST $DST" \ "Error cloning $RBD_DST to $DST in $SRC_HOST" diff --git a/src/tm_mad/ceph/mvds b/src/tm_mad/ceph/mvds index f64234933d..55e35ec3a4 100755 --- a/src/tm_mad/ceph/mvds +++ b/src/tm_mad/ceph/mvds @@ -22,85 +22,4 @@ # - host is the target host to deploy the VM # - remote_system_ds is the path for the system datastore in the host -SRC=$1 -DST=$2 -VM_ID=$3 -DS_ID=$4 - -if [ -z "${ONE_LOCATION}" ]; then - TMCOMMON=/var/lib/one/remotes/tm/tm_common.sh -else - TMCOMMON=$ONE_LOCATION/var/remotes/tm/tm_common.sh -fi - -DRIVER_PATH=$(dirname $0) - -source $TMCOMMON -source ${DRIVER_PATH}/../../datastore/ceph/ceph.conf - -#------------------------------------------------------------------------------- -# Set dst path and dir -#------------------------------------------------------------------------------- - -SRC_HOST=`arg_host $SRC` -SRC_PATH=`arg_path $SRC` - -#------------------------------------------------------------------------------- -# Get Image information -#------------------------------------------------------------------------------- - -DISK_ID=$(echo "$SRC_PATH" | $AWK -F. '{print $NF}') - -XPATH="${DRIVER_PATH}/../../datastore/xpath.rb --stdin" - -unset i j XPATH_ELEMENTS - -while IFS= read -r -d '' element; do - XPATH_ELEMENTS[i++]="$element" -done < <(onevm show -x $VM_ID| $XPATH \ - /VM/TEMPLATE/DISK[DISK_ID=$DISK_ID]/SOURCE \ - /VM/TEMPLATE/DISK[DISK_ID=$DISK_ID]/CLONE \ - /VM/TEMPLATE/DISK[DISK_ID=$DISK_ID]/CEPH_USER) - -RBD_SRC="${XPATH_ELEMENTS[j++]}" -CLONE="${XPATH_ELEMENTS[j++]}" -CEPH_USER="${XPATH_ELEMENTS[j++]}" - -# No need to copy back to datastore no cloned images -if [ "$CLONE" = "NO" ]; then - exit 0 -fi - -if [ -n "$CEPH_USER" ]; then - RBD="$RBD --id ${CEPH_USER}" -fi - -# cloned, so the name will be "/one---" -RBD_DST="${RBD_SRC}-${VM_ID}-${DISK_ID}" -RBD_SNAP="${VM_ID}-${DISK_ID}" - -#------------------------------------------------------------------------------- -# Move the image back to the datastore -#------------------------------------------------------------------------------- - -log "Dumping $RBD_DST to $DST" - -DUMP_CMD=$(cat < Date: Thu, 11 Jun 2015 18:22:08 +0200 Subject: [PATCH 11/15] feature #3782: Update all cpds to include the SNAP_ID parameter --- src/tm_mad/ceph/cpds | 1 - src/tm_mad/fs_lvm/cpds | 8 +++++--- src/tm_mad/lvm/cpds | 8 +++++--- src/tm_mad/shared/cpds | 11 +++++------ src/tm_mad/ssh/cpds | 11 +++++------ src/tm_mad/vmfs/mvds | 11 +++++------ 6 files changed, 25 insertions(+), 25 deletions(-) diff --git a/src/tm_mad/ceph/cpds b/src/tm_mad/ceph/cpds index c194032aec..a811614c58 100755 --- a/src/tm_mad/ceph/cpds +++ b/src/tm_mad/ceph/cpds @@ -16,7 +16,6 @@ # limitations under the License. # #--------------------------------------------------------------------------- # -# mvds host:remote_system_ds/disk.i fe:SOURCE # cpds host:remote_system_ds/disk.i fe:SOURCE snapid vmid dsid # - fe is the front-end hostname # - SOURCE is the path of the disk image in the form DS_BASE_PATH/disk diff --git a/src/tm_mad/fs_lvm/cpds b/src/tm_mad/fs_lvm/cpds index f4df668072..6e88b772da 100755 --- a/src/tm_mad/fs_lvm/cpds +++ b/src/tm_mad/fs_lvm/cpds @@ -16,16 +16,18 @@ # limitations under the License. # #--------------------------------------------------------------------------- # -# mvds host:remote_system_ds/disk.i fe:SOURCE +# cpds host:remote_system_ds/disk.i fe:SOURCE snapid vmid dsid # - fe is the front-end hostname # - SOURCE is the path of the disk image in the form DS_BASE_PATH/disk # - host is the target host to deploy the VM # - remote_system_ds is the path for the system datastore in the host +# - snapid is the snapshot id. "-1" for none SRC=$1 DST=$2 -VM_ID=$3 -DS_ID=$4 +SNAP_ID=$3 +VM_ID=$4 +DS_ID=$5 if [ -z "${ONE_LOCATION}" ]; then TMCOMMON=/var/lib/one/remotes/tm/tm_common.sh diff --git a/src/tm_mad/lvm/cpds b/src/tm_mad/lvm/cpds index 8532363507..c97379f250 100755 --- a/src/tm_mad/lvm/cpds +++ b/src/tm_mad/lvm/cpds @@ -16,16 +16,18 @@ # limitations under the License. # #--------------------------------------------------------------------------- # -# mvds host:remote_system_ds/disk.i fe:SOURCE +# cpds host:remote_system_ds/disk.i fe:SOURCE snapid vmid dsid # - fe is the front-end hostname # - SOURCE is the path of the disk image in the form DS_BASE_PATH/disk # - host is the target host to deploy the VM # - remote_system_ds is the path for the system datastore in the host +# - snapid is the snapshot id. "-1" for none SRC=$1 DST=$2 -VM_ID=$3 -DS_ID=$4 +SNAP_ID=$3 +VM_ID=$4 +DS_ID=$5 if [ -z "${ONE_LOCATION}" ]; then TMCOMMON=/var/lib/one/remotes/tm/tm_common.sh diff --git a/src/tm_mad/shared/cpds b/src/tm_mad/shared/cpds index 1a898ad2ba..fae3b52e8b 100755 --- a/src/tm_mad/shared/cpds +++ b/src/tm_mad/shared/cpds @@ -16,19 +16,18 @@ # limitations under the License. # #--------------------------------------------------------------------------- # -# mvds host:remote_system_ds/disk.i fe:SOURCE vmid dsid +# cpds host:remote_system_ds/disk.i fe:SOURCE snapid vmid dsid # - fe is the front-end hostname # - SOURCE is the path of the disk image in the form DS_BASE_PATH/disk # - host is the target host to deploy the VM # - remote_system_ds is the path for the system datastore in the host -# - vmid is the id of the VM -# - dsid is the target datastore (0 is the system datastore) +# - snapid is the snapshot id. "-1" for none SRC=$1 DST=$2 - -VMID=$3 -DSID=$4 +SNAP_ID=$3 +VMID=$4 +DSID=$5 if [ -z "${ONE_LOCATION}" ]; then TMCOMMON=/var/lib/one/remotes/tm/tm_common.sh diff --git a/src/tm_mad/ssh/cpds b/src/tm_mad/ssh/cpds index e42b11feb7..2a7d64f691 100755 --- a/src/tm_mad/ssh/cpds +++ b/src/tm_mad/ssh/cpds @@ -16,19 +16,18 @@ # limitations under the License. # #--------------------------------------------------------------------------- # -# cpds host:remote_system_ds/disk.i fe:SOURCE vmid dsid +# cpds host:remote_system_ds/disk.i fe:SOURCE snapid vmid dsid # - fe is the front-end hostname # - SOURCE is the path of the disk image in the form DS_BASE_PATH/disk # - host is the target host to deploy the VM # - remote_system_ds is the path for the system datastore in the host -# - vmid is the id of the VM -# - dsid is the target datastore (0 is the system datastore) +# - snapid is the snapshot id. "-1" for none SRC=$1 DST=$2 - -VMID=$3 -DSID=$4 +SNAP_ID=$3 +VMID=$4 +DSID=$5 if [ -z "${ONE_LOCATION}" ]; then TMCOMMON=/var/lib/one/remotes/tm/tm_common.sh diff --git a/src/tm_mad/vmfs/mvds b/src/tm_mad/vmfs/mvds index 59815c0869..824c08ac62 100755 --- a/src/tm_mad/vmfs/mvds +++ b/src/tm_mad/vmfs/mvds @@ -16,19 +16,18 @@ # limitations under the License. # #--------------------------------------------------------------------------- # -# mvds host:remote_system_ds/disk.i fe:SOURCE vmid dsid +# cpds host:remote_system_ds/disk.i fe:SOURCE snapid vmid dsid # - fe is the front-end hostname # - SOURCE is the path of the disk image in the form DS_BASE_PATH/disk # - host is the target host to deploy the VM # - remote_system_ds is the path for the system datastore in the host -# - vmid is the id of the VM -# - dsid is the target datastore (0 is the system datastore) +# - snapid is the snapshot id. "-1" for none SRC=$1 DST=$2 - -VMID=$3 -DSID=$4 +SNAP_ID=$3 +VMID=$4 +DSID=$5 if [ -z "${ONE_LOCATION}" ]; then TMCOMMON=/var/lib/one/remotes/tm/tm_common.sh From b5136a152ffdb15e30dc5e3accfa83581319fc24 Mon Sep 17 00:00:00 2001 From: Jaime Melis Date: Fri, 12 Jun 2015 17:50:09 +0200 Subject: [PATCH 12/15] Feature #3782: Remove debugging data --- src/tm_mad/ceph/cpds | 1 - 1 file changed, 1 deletion(-) diff --git a/src/tm_mad/ceph/cpds b/src/tm_mad/ceph/cpds index a811614c58..32c8b5146c 100755 --- a/src/tm_mad/ceph/cpds +++ b/src/tm_mad/ceph/cpds @@ -86,7 +86,6 @@ if [ -n "$CEPH_USER" ]; then RBD="$RBD --id ${CEPH_USER}" fi -echo "$RBD copy $RBD_DST $DST" > /tmp/k ssh_exec_and_log "$SRC_HOST" "$RBD copy $RBD_DST $DST" \ "Error cloning $RBD_DST to $DST in $SRC_HOST" From 1b531f82ff39d8cd4fa350ebe996f48603865d6f Mon Sep 17 00:00:00 2001 From: Jaime Melis Date: Fri, 12 Jun 2015 17:50:28 +0200 Subject: [PATCH 13/15] Feature #3782: Simplify all TM/mvds action as now they don't handle deferred saveas --- src/tm_mad/ceph/mvds | 6 ---- src/tm_mad/lvm/mvds | 48 ---------------------------- src/tm_mad/qcow2/mvds | 56 -------------------------------- src/tm_mad/shared/mvds | 56 -------------------------------- src/tm_mad/vmfs/mvds | 72 ------------------------------------------ 5 files changed, 238 deletions(-) diff --git a/src/tm_mad/ceph/mvds b/src/tm_mad/ceph/mvds index 55e35ec3a4..8c976fe703 100755 --- a/src/tm_mad/ceph/mvds +++ b/src/tm_mad/ceph/mvds @@ -16,10 +16,4 @@ # limitations under the License. # #--------------------------------------------------------------------------- # -# mvds host:remote_system_ds/disk.i fe:SOURCE -# - fe is the front-end hostname -# - SOURCE is the path of the disk image in the form DS_BASE_PATH/disk -# - host is the target host to deploy the VM -# - remote_system_ds is the path for the system datastore in the host - exit 0 diff --git a/src/tm_mad/lvm/mvds b/src/tm_mad/lvm/mvds index 1d80718a1b..55e35ec3a4 100755 --- a/src/tm_mad/lvm/mvds +++ b/src/tm_mad/lvm/mvds @@ -22,52 +22,4 @@ # - host is the target host to deploy the VM # - remote_system_ds is the path for the system datastore in the host -SRC=$1 -DST=$2 -VM_ID=$3 -DS_ID=$4 - -if [ -z "${ONE_LOCATION}" ]; then - TMCOMMON=/var/lib/one/remotes/tm/tm_common.sh -else - TMCOMMON=$ONE_LOCATION/var/remotes/tm/tm_common.sh -fi - -DRIVER_PATH=$(dirname $0) - -source $TMCOMMON -source ${DRIVER_PATH}/../../datastore/lvm/lvm.conf - -#------------------------------------------------------------------------------- -# Set dst path and dir -#------------------------------------------------------------------------------- -SRC_PATH=`arg_path $SRC` -SRC_HOST=`arg_host $SRC` - -DST_PATH=`arg_path $DST` -DST_HOST=`arg_host $DST` - -VG_NAME=$(echo $DST_PATH|cut -d. -f1) -LV_NAME=$(echo $DST_PATH|cut -d. -f2) - -TARGET_DEV=/dev/$VG_NAME/$LV_NAME - -DUMP_CMD=$(cat < Date: Mon, 15 Jun 2015 23:28:38 +0200 Subject: [PATCH 14/15] feature #3782: Fix comment --- src/tm/TransferManager.cc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/tm/TransferManager.cc b/src/tm/TransferManager.cc index 80f479fbc1..c4d95f34fd 100644 --- a/src/tm/TransferManager.cc +++ b/src/tm/TransferManager.cc @@ -2106,7 +2106,7 @@ void TransferManager::saveas_hot_action(int vid) goto error_file; } - //MVDS tm_mad hostname:remote_system_dir/disk.0 source snapid vmid dsid + //CPDS tm_mad hostname:remote_system_dir/disk.0 source snapid vmid dsid xfr << "CPDS " << tm_mad << " " << vm->get_hostname() << ":" From 32832269e5c1e97c35c885706280e49ded0ecad2 Mon Sep 17 00:00:00 2001 From: "Ruben S. Montero" Date: Tue, 16 Jun 2015 01:59:24 +0200 Subject: [PATCH 15/15] feature #3782: Fix return codes --- src/rm/RequestManagerImage.cc | 6 +++--- src/rm/RequestManagerVirtualMachine.cc | 4 ++-- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/src/rm/RequestManagerImage.cc b/src/rm/RequestManagerImage.cc index f13dc45170..958804f420 100644 --- a/src/rm/RequestManagerImage.cc +++ b/src/rm/RequestManagerImage.cc @@ -495,7 +495,7 @@ void ImageSnapshotDelete::request_execute(xmlrpc_c::paramList const& paramList, return; } - success_response(id, att); + success_response(snap_id, att); } /* ------------------------------------------------------------------------- */ @@ -524,7 +524,7 @@ void ImageSnapshotRevert::request_execute(xmlrpc_c::paramList const& paramList, return; } - success_response(id, att); + success_response(snap_id, att); } /* ------------------------------------------------------------------------- */ @@ -553,6 +553,6 @@ void ImageSnapshotFlatten::request_execute(xmlrpc_c::paramList const& paramList, return; } - success_response(id, att); + success_response(snap_id, att); } diff --git a/src/rm/RequestManagerVirtualMachine.cc b/src/rm/RequestManagerVirtualMachine.cc index a2390fd4dc..b29f0f13f5 100644 --- a/src/rm/RequestManagerVirtualMachine.cc +++ b/src/rm/RequestManagerVirtualMachine.cc @@ -2404,7 +2404,7 @@ void VirtualMachineDiskSnapshotRevert::request_execute( } else { - success_response(id, att); + success_response(snap_id, att); } return; @@ -2443,7 +2443,7 @@ void VirtualMachineDiskSnapshotDelete::request_execute( } else { - success_response(id, att); + success_response(snap_id, att); } return;