diff --git a/include/Quotas.h b/include/Quotas.h index b8303e9266..b9ee9a0b45 100644 --- a/include/Quotas.h +++ b/include/Quotas.h @@ -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 diff --git a/src/image/Image.cc b/src/image/Image.cc index e4f3435962..55b9638011 100644 --- a/src/image/Image.cc +++ b/src/image/Image.cc @@ -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; diff --git a/src/image/ImageManagerActions.cc b/src/image/ImageManagerActions.cc index 68146bfe86..91543c024c 100644 --- a/src/image/ImageManagerActions.cc +++ b/src/image/ImageManagerActions.cc @@ -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 diff --git a/src/image/ImageManagerProtocol.cc b/src/image/ImageManagerProtocol.cc index 22c0fb58b5..0ccdf8588f 100644 --- a/src/image/ImageManagerProtocol.cc +++ b/src/image/ImageManagerProtocol.cc @@ -163,9 +163,9 @@ void ImageManager::_clone(unique_ptr 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 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 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 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 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);