From 2ce40099751f10af2de93777b524e0551ab8a38b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Carlos=20Mart=C3=ADn?= Date: Mon, 11 Apr 2011 18:05:43 +0200 Subject: [PATCH] Feature #523: Extra error checks for one.vm.savedisk XML-RPC method --- include/VirtualMachine.h | 2 +- src/rm/RequestManagerImagePersistent.cc | 3 +- src/rm/RequestManagerSaveDisk.cc | 56 +++++++++++++++++++++---- src/vm/VirtualMachine.cc | 22 +++++++++- 4 files changed, 71 insertions(+), 12 deletions(-) diff --git a/include/VirtualMachine.h b/include/VirtualMachine.h index 82a540403d..9c510d831f 100644 --- a/include/VirtualMachine.h +++ b/include/VirtualMachine.h @@ -656,7 +656,7 @@ public: * @param img_id ID of the image this disk will be saved to. * @return 0 if success */ - int save_disk(int disk_id, int img_id); + int save_disk(int disk_id, int img_id, string& error_str); private: diff --git a/src/rm/RequestManagerImagePersistent.cc b/src/rm/RequestManagerImagePersistent.cc index a2af64fad1..cc00ba7f3e 100644 --- a/src/rm/RequestManagerImagePersistent.cc +++ b/src/rm/RequestManagerImagePersistent.cc @@ -137,8 +137,7 @@ error_authorize: error_persistent: image->unlock(); - oss << action_error(method_name, "MANAGE", "IMAGE", iid, 0) - << " Is the image public? An Image cannot be public and persistent."; + oss.str(action_error(method_name, "MANAGE", "IMAGE", iid, 0)); goto error_common; error_common: diff --git a/src/rm/RequestManagerSaveDisk.cc b/src/rm/RequestManagerSaveDisk.cc index f34882cf02..512efcc3cd 100644 --- a/src/rm/RequestManagerSaveDisk.cc +++ b/src/rm/RequestManagerSaveDisk.cc @@ -39,7 +39,8 @@ void RequestManager::VirtualMachineSaveDisk::execute( int rc; int uid; string estr; - char * error_str; + char * error_char; + string error_str; const string method_name = "VirtualMachineSaveDisk"; @@ -48,6 +49,10 @@ void RequestManager::VirtualMachineSaveDisk::execute( ImageTemplate * img_template; User * user; + Image * source_img; + int source_img_id; + bool source_img_persistent = false; + vector arrayData; xmlrpc_c::value_array * arrayresult; @@ -92,7 +97,7 @@ void RequestManager::VirtualMachineSaveDisk::execute( if ( image != 0 ) { - goto error_image_get; + goto error_image_exists; } oss << "NAME= " << img_name << endl; @@ -101,7 +106,7 @@ void RequestManager::VirtualMachineSaveDisk::execute( img_template = new ImageTemplate; - img_template->parse(oss.str(),&error_str); + img_template->parse(oss.str(),&error_char); oss.str(""); @@ -158,7 +163,7 @@ void RequestManager::VirtualMachineSaveDisk::execute( oss.str(""); //-------------------------------------------------------------------------- - // Store image id to save the disk in the VM template + // Get the VM //-------------------------------------------------------------------------- vm = VirtualMachineSaveDisk::vmpool->get(vm_id,true); @@ -167,7 +172,35 @@ void RequestManager::VirtualMachineSaveDisk::execute( goto error_vm_get; } - rc = vm->save_disk(disk_id, iid); + //-------------------------------------------------------------------------- + // Check if the disk has a persistent source image + //-------------------------------------------------------------------------- + oss << "/VM/TEMPLATE/DISK[DISK_ID=" << disk_id << "]/IMAGE_ID"; + rc = vm->xpath(source_img_id, oss.str().c_str(), -1); + oss.str(""); + + if( rc == 0 ) // The disk was created from an Image + { + source_img = VirtualMachineSaveDisk::ipool->get(source_img_id, true); + + if( source_img != 0 ) // The Image still exists + { + source_img_persistent = source_img->isPersistent(); + source_img->unlock(); + + if( source_img_persistent ) + { + vm->unlock(); + goto error_img_persistent; + } + } + } + + //-------------------------------------------------------------------------- + // Store image id to save the disk in the VM template + //-------------------------------------------------------------------------- + + rc = vm->save_disk(disk_id, iid, error_str); if ( rc == -1 ) { @@ -193,18 +226,25 @@ void RequestManager::VirtualMachineSaveDisk::execute( return; -error_image_get: +error_image_exists: oss << action_error(method_name, "CREATE", "IMAGE", -2, 0); - oss << ". Image " << img_name << " already exists in the repository."; + oss << " Image " << img_name << " already exists in the repository."; goto error_common; error_vm_get: oss.str(get_error(method_name, "VM", vm_id)); goto error_common; +error_img_persistent: + oss << action_error(method_name, "SAVEDISK", "DISK", disk_id, 0); + oss << " Source IMAGE " << source_img_id << " is persistent."; + + goto error_common; + error_vm_get_disk_id: oss.str(get_error(method_name, "DISK from VM", vm_id)); - oss << ". Deleting Image " << img_name; + oss << " " << error_str; + oss << " Deleting Image " << img_name; imagem->delete_image(iid); goto error_common; diff --git a/src/vm/VirtualMachine.cc b/src/vm/VirtualMachine.cc index b495cce75f..e14e9b821b 100644 --- a/src/vm/VirtualMachine.cc +++ b/src/vm/VirtualMachine.cc @@ -951,7 +951,7 @@ int VirtualMachine::generate_context(string &files) /* -------------------------------------------------------------------------- */ /* -------------------------------------------------------------------------- */ -int VirtualMachine::save_disk(int disk_id, int img_id) +int VirtualMachine::save_disk(int disk_id, int img_id, string& error_str) { int num_disks; vector disks; @@ -959,6 +959,8 @@ int VirtualMachine::save_disk(int disk_id, int img_id) string disk_id_str; int tmp_disk_id; + string tmp_img_id_str; + int tmp_img_id; ostringstream oss; istringstream iss; @@ -982,6 +984,11 @@ int VirtualMachine::save_disk(int disk_id, int img_id) if( tmp_disk_id == disk_id ) { + if( disk->vector_value("SAVE_AS") != "" ) + { + goto error_saved; + } + disk->replace("SAVE", "YES"); oss << (img_id); @@ -991,6 +998,19 @@ int VirtualMachine::save_disk(int disk_id, int img_id) } } + goto error_not_found; + +error_saved: + oss << "The DISK " << disk_id << " is already suppossed to be saved."; + goto error_common; + +error_not_found: + oss << "The DISK " << disk_id << " does not exist for VM " << oid << "."; + +error_common: + NebulaLog::log("VM",Log::ERROR, oss); + error_str = oss.str(); + return -1; }