1
0
mirror of https://github.com/OpenNebula/one.git synced 2025-03-25 02:50:08 +03:00

Bug #804: Better image release rollback when a VM can't be created

This commit is contained in:
Carlos Martín 2011-09-15 19:06:16 +02:00
parent 5a39c6b5bd
commit 91d554b3aa
5 changed files with 67 additions and 27 deletions

View File

@ -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);
/**

View File

@ -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

View File

@ -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;

View File

@ -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");

View File

@ -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<Attribute * > disks;
ImagePool * ipool;
VectorAttribute * disk;
vector<int> 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<int>::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;
}