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

F #5925: Fix quotas after image delete failure (#2408)

* Fix quotas after image delete failure
* Fix set backup state after delete failure
This commit is contained in:
Pavel Czerný 2022-12-07 09:39:03 +01:00 committed by GitHub
parent 777b5fd6f0
commit d8baeb028e
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
4 changed files with 87 additions and 69 deletions

View File

@ -194,6 +194,26 @@ public:
quota_del(DATASTORE, uid, gid, tmpl);
}
/**
* Delete Datastore related usage from quota counters.
* for the given user and group
* @param uid of the user
* @param gid of the group
* @param ds_id datastore ID
* @param size size of the image
* @param images number of images
*/
static void ds_del(int uid, int gid, int ds_id, long long size, int images = 1)
{
Template img_usage;
img_usage.add("DATASTORE", ds_id);
img_usage.add("SIZE", size);
img_usage.add("IMAGES", images);
Quotas::ds_del(uid, gid, &img_usage);
}
/**
* Delete Datastore related usage from quota counters.
* for the given user and group

View File

@ -1004,11 +1004,6 @@ Image::DiskType Image::str_to_disk_type(string& s_disk_type)
void Image::set_state(ImageState _state)
{
if ( type == Image::BACKUP ) //Backups in READY state at creation
{
return;
}
if (_state == ERROR && (state == LOCKED_USED || state == LOCKED_USED_PERS))
{
LifeCycleManager* lcm = Nebula::instance().get_lcm();
@ -1037,11 +1032,6 @@ void Image::set_state(ImageState _state)
void Image::set_state_unlock()
{
if ( type == Image::BACKUP ) //Backups in READY state at creation
{
return;
}
LifeCycleManager* lcm = Nebula::instance().get_lcm();
bool vms_notify = false;

View File

@ -458,12 +458,7 @@ int ImageManager::delete_image(int iid, string& error_str)
string img_tmpl;
string ds_data;
long long size;
long long snap_size;
int ds_id;
int uid;
int gid;
int cloning_id = -1;
int vm_saving_id = -1;
@ -555,10 +550,6 @@ int ImageManager::delete_image(int iid, string& error_str)
}
source = img->get_source();
size = img->get_size();
ds_id = img->get_ds_id();
uid = img->get_uid();
gid = img->get_gid();
if (source.empty())
{
@ -571,6 +562,23 @@ int ImageManager::delete_image(int iid, string& error_str)
{
NebulaLog::log("ImM",Log::ERROR,
"Image could not be removed from DB");
return -1;
}
int uid = img->get_uid();
int gid = img->get_gid();
long long size = img->get_size() + img->get_snapshots().get_total_size();
img.reset();
Quotas::ds_del(uid, gid, ds_id, size);
// Remove Image reference from Datastore
if ( auto ds = dspool->get(ds_id) )
{
ds->del_image(iid);
dspool->update(ds.get());
}
}
else
@ -586,21 +594,10 @@ int ImageManager::delete_image(int iid, string& error_str)
img->clear_cloning_id();
ipool->update(img.get());
img.reset();
}
snap_size = (img->get_snapshots()).get_total_size();
img.reset();
/* -------------------- Update Group & User quota counters -------------- */
Template img_usage;
img_usage.add("DATASTORE", ds_id);
img_usage.add("SIZE", size + snap_size);
Quotas::ds_del(uid, gid, &img_usage);
/* --------------- Update cloning image if needed ----------------------- */
if ( cloning_id != -1 )
@ -608,12 +605,6 @@ int ImageManager::delete_image(int iid, string& error_str)
release_cloning_image(cloning_id, iid);
}
if ( auto ds = dspool->get(ds_id) )
{
ds->del_image(iid);
dspool->update(ds.get());
}
/* --------------- Release VM in hotplug -------------------------------- */
// This is only needed if the image is deleted before the mkfs action

View File

@ -163,9 +163,9 @@ void ImageManager::_clone(unique_ptr<image_msg_t> msg)
ostringstream oss;
istringstream is(info);
NebulaLog::dddebug("ImM", "_clone: " + info);
is >> skipws;
auto image = ipool->get(msg->oid());
@ -435,22 +435,52 @@ void ImageManager::_rm(unique_ptr<image_msg_t> msg)
{
NebulaLog::dddebug("ImM", "_rm: " + msg->payload());
int img_id = msg->oid();
int ds_id = -1;
int uid;
int gid;
int rc;
string tmp_error;
string source;
long long size;
long long snap_size;
ostringstream oss;
int backup_vm_id = -1;
bool success = msg->status() == "SUCCESS";
if ( auto image = ipool->get(msg->oid()) )
if ( auto image = ipool->get(img_id) )
{
bool force = false;
image->get_template_attribute("FORCE_DELETE", force);
success = success || force;
if (!success)
{
oss << "Error removing image from datastore. Retry the operation "
<< "or manually remove image source " << source << " and run "
<< "the delete --force operation to completely delete the image";
image->set_template_error_message(oss.str());
image->set_state(Image::ERROR);
ipool->update(image.get());
goto error;
}
ds_id = image->get_ds_id();
uid = image->get_uid();
gid = image->get_gid();
source = image->get_source();
size = image->get_size();
snap_size = (image->get_snapshots()).get_total_size();
if ( image->get_type() == Image::BACKUP )
{
@ -463,26 +493,11 @@ void ImageManager::_rm(unique_ptr<image_msg_t> msg)
}
}
bool force = false;
image->get_template_attribute("FORCE_DELETE", force);
rc = ipool->drop(image.get(), tmp_error);
success = success || force;
if (success)
if (rc < 0)
{
rc = ipool->drop(image.get(), tmp_error);
}
else
{
oss << "Error removing image from datastore. Retry the operation "
<< "or manually remove image source " << source << " and run "
<< "the delete --force operation to completely delete the image";
image->set_template_error_message(oss.str());
image->set_state(Image::ERROR);
ipool->update(image.get());
goto error_drop;
}
}
else
@ -490,13 +505,24 @@ void ImageManager::_rm(unique_ptr<image_msg_t> msg)
return;
}
// Remove Image reference from Datastore
if ( auto ds = dspool->get(ds_id) )
{
ds->del_image(img_id);
dspool->update(ds.get());
}
// Update Group & User quota counters
Quotas::ds_del(uid, gid, ds_id, size + snap_size);
// Remove Image reference from VM backups
if ( backup_vm_id != -1 )
{
VirtualMachinePool * vmpool = Nebula::instance().get_vmpool();
if ( auto vm = vmpool->get(backup_vm_id) )
{
vm->backups().del(msg->oid());
vm->backups().del(img_id);
vmpool->update(vm.get());
}
@ -504,15 +530,6 @@ void ImageManager::_rm(unique_ptr<image_msg_t> msg)
// TODO BACKUP QUOTA ROLLBACK
}
if (!success)
{
goto error;
}
else if (rc < 0)
{
goto error_drop;
}
NebulaLog::info("ImM", "Image successfully removed.");
monitor_datastore(ds_id);