diff --git a/include/ImageManager.h b/include/ImageManager.h index 4e7daca0dd..de14c32455 100644 --- a/include/ImageManager.h +++ b/include/ImageManager.h @@ -96,6 +96,27 @@ public: void release_image(const string& iid, const string& disk_path, int disk_num, + const string& saveid) + { + int image_id; + istringstream iss; + + iss.str(iid); + iss >> image_id; + + return release_image(image_id, disk_path, disk_num, saveid); + }; + + /** + * Releases an image and triggers any needed operations in the repo + * @param iid image id of the image to be released + * @param disk_path base path for disk location + * @param disk number for this image in the VM + * @param saveid id of image to save the current image + */ + void release_image(int iid, + const string& disk_path, + int disk_num, const string& saveid); /** diff --git a/include/ImagePool.h b/include/ImagePool.h index d69a2f3a60..78052d7349 100644 --- a/include/ImagePool.h +++ b/include/ImagePool.h @@ -130,6 +130,7 @@ public: * automatically increased. * @param img_type will be set to the used image's type * @param uid of VM owner (to look for the image id within its images) + * @param image_id on success returns the acquired image id * @return 0 on success, * -1 error, * -2 not using the pool, @@ -139,7 +140,8 @@ public: int disk_id, int * index, Image::ImageType * img_type, - int uid); + int uid, + int& image_id); /** * Generates an Authorization token for the DISK attribute * @param disk the disk to be authorized diff --git a/src/image/ImageManagerActions.cc b/src/image/ImageManagerActions.cc index 1d3cdd8dec..769c8dffbf 100644 --- a/src/image/ImageManagerActions.cc +++ b/src/image/ImageManagerActions.cc @@ -141,14 +141,13 @@ void ImageManager::disk_to_image(const string& disk_path, /* -------------------------------------------------------------------------- */ /* -------------------------------------------------------------------------- */ -void ImageManager::release_image(const string& image_id, +void ImageManager::release_image(int iid, const string& disk_path, int disk_num, const string& save_id) { int rvms; - int iid; int sid = -1; istringstream iss; @@ -156,13 +155,8 @@ void ImageManager::release_image(const string& image_id, ostringstream disk_file; - iss.str(image_id); - - iss >> iid; - if ( save_id.empty() == false ) { - iss.clear(); iss.str(save_id); iss >> sid; @@ -180,7 +174,7 @@ void ImageManager::release_image(const string& image_id, case Image::USED: rvms = img->dec_running(); - if ( img->isPersistent() ) + if ( img->isPersistent() && !disk_path.empty() ) { disk_file << disk_path << "/disk." << disk_num; diff --git a/src/image/ImagePool.cc b/src/image/ImagePool.cc index 69931e6798..f64a0bb386 100644 --- a/src/image/ImagePool.cc +++ b/src/image/ImagePool.cc @@ -131,7 +131,8 @@ int ImagePool::disk_attribute(VectorAttribute * disk, int disk_id, int * index, Image::ImageType * img_type, - int uid) + int uid, + int& image_id) { string source; Image * img = 0; @@ -143,7 +144,6 @@ int ImagePool::disk_attribute(VectorAttribute * disk, ImageManager * imagem = nd.get_imagem(); istringstream is; - int image_id; source = disk->vector_value("IMAGE"); diff --git a/src/vm/VirtualMachine.cc b/src/vm/VirtualMachine.cc index 99a082ca9c..b7dbc1b66a 100644 --- a/src/vm/VirtualMachine.cc +++ b/src/vm/VirtualMachine.cc @@ -220,7 +220,7 @@ int VirtualMachine::insert(SqlDB * db, string& error_str) if ( rc != 0 ) { - goto error_leases; + goto error_leases_rollback; } // ------------------------------------------------------------------------ @@ -231,7 +231,9 @@ int VirtualMachine::insert(SqlDB * db, string& error_str) if ( rc != 0 ) { - goto error_images; + // The get_disk_images method has an internal rollback for + // the acquired images, release_disk_images() would release all disks + goto error_leases_rollback; } // ------------------------------------------------------------------------- @@ -269,26 +271,24 @@ int VirtualMachine::insert(SqlDB * db, string& error_str) error_update: error_str = "Can not insert VM in the database."; - goto error_common; - -error_leases: - NebulaLog::log("ONE",Log::ERROR, error_str); - release_network_leases(); - return -1; - -error_images: - goto error_common; + goto error_rollback; error_context: - goto error_common; + goto error_rollback; error_requirements: - goto error_common; + goto error_rollback; + +error_rollback: + release_disk_images(); + +error_leases_rollback: + release_network_leases(); + goto error_common; // just to avoid compilation warnings error_common: NebulaLog::log("ONE",Log::ERROR, error_str); - release_network_leases(); - release_disk_images(); + return -1; } @@ -663,11 +663,13 @@ int VirtualMachine::get_disk_images(string& error_str) vector disks; ImagePool * ipool; VectorAttribute * disk; + vector acquired_images; int n_os = 0; // Number of OS images int n_cd = 0; // Number of CDROMS int n_db = 0; // Number of DATABLOCKS string type; + int image_id; ostringstream oss; Image::ImageType img_type; @@ -686,10 +688,12 @@ int VirtualMachine::get_disk_images(string& error_str) continue; } - rc = ipool->disk_attribute(disk, i, &index, &img_type, uid); + rc = ipool->disk_attribute(disk, i, &index, &img_type, uid, image_id); if (rc == 0 ) { + acquired_images.push_back(image_id); + switch(img_type) { case Image::OS: @@ -728,6 +732,10 @@ int VirtualMachine::get_disk_images(string& error_str) { goto error_name; } + else if ( rc != -2 ) // The only known code left + { + goto error_unknown; + } } return 0; @@ -750,8 +758,23 @@ error_image: error_name: error_str = "IMAGE is not supported for DISK. Use IMAGE_ID instead."; + goto error_common; + +error_unknown: + error_str = "Unknown error code."; error_common: + ImageManager * imagem = nd.get_imagem(); + + vector::iterator it; + + for ( it=acquired_images.begin() ; it < acquired_images.end(); it++ ) + { + // Set disk_path and save_id to empty string, this way the image manager + // won't try to move any files + imagem->release_image(*it,"",-1,""); + } + return -1; }