From 0bbb99a2405604deff0cea4ef99112abe4a51fce Mon Sep 17 00:00:00 2001 From: "Ruben S. Montero" Date: Fri, 5 Jun 2015 13:32:00 +0200 Subject: [PATCH] feature #3782: Image are in LOCKED state while performing snapshot operations --- include/Snapshots.h | 12 ++++++ src/image/ImageManagerActions.cc | 69 +++++++++++++++++++++++++------- src/image/ImageManagerDriver.cc | 8 ++++ 3 files changed, 74 insertions(+), 15 deletions(-) diff --git a/include/Snapshots.h b/include/Snapshots.h index 098110eced..eba353bf01 100644 --- a/include/Snapshots.h +++ b/include/Snapshots.h @@ -143,6 +143,18 @@ public: return snapshot_pool.size(); }; + /** + * Check if snapshot exists + * @param snap_id of the snapshot + * @return true if the snapshot with snap_id exisits + */ + bool exists(int snap_id) const + { + const VectorAttribute * snap = get_snapshot(snap_id); + + return (snap != 0); + } + /** * Get Attribute from the given snapshot * @param id of the snapshot diff --git a/src/image/ImageManagerActions.cc b/src/image/ImageManagerActions.cc index aa5f5c5930..3cf9c5c5f4 100644 --- a/src/image/ImageManagerActions.cc +++ b/src/image/ImageManagerActions.cc @@ -918,21 +918,10 @@ void ImageManager::set_image_snapshots(int iid, const Snapshots& s, bool failed) return; } - switch (img->get_state()) + if (img->get_state() != Image::USED_PERS) { - case Image::USED_PERS: - break; - - case Image::USED: - case Image::LOCKED: - case Image::CLONE: - case Image::DELETE: - case Image::INIT: - case Image::DISABLED: - case Image::READY: - case Image::ERROR: - img->unlock(); - return; + img->unlock(); + return; } img->set_snapshots(s); @@ -957,6 +946,11 @@ int ImageManager::delete_snapshot(int iid, int sid, string& error) return -1; } + /* ---------------------------------------------------------------------- */ + /* Check action consistency: */ + /* state is READY */ + /* snapshot can be deleted (not active, no childs, exists) */ + /* ---------------------------------------------------------------------- */ Image * img = ipool->get(iid,true); if ( img == 0 ) @@ -965,6 +959,13 @@ int ImageManager::delete_snapshot(int iid, int sid, string& error) return -1; } + if (img->get_state() != Image::READY) + { + error = "Cannot delete snapshot in state " + Image::state_to_str(img->get_state()); + img->unlock(); + return -1; + } + const Snapshots& snaps = img->get_snapshots(); if (!snaps.test_delete(sid, error)) @@ -973,6 +974,9 @@ int ImageManager::delete_snapshot(int iid, int sid, string& error) return -1; } + /* ---------------------------------------------------------------------- */ + /* Get DS data for driver */ + /* ---------------------------------------------------------------------- */ int ds_id = img->get_ds_id(); img->unlock(); @@ -993,6 +997,9 @@ int ImageManager::delete_snapshot(int iid, int sid, string& error) img = ipool->get(iid,true); + /* ---------------------------------------------------------------------- */ + /* Format message and send action to driver */ + /* ---------------------------------------------------------------------- */ if ( img == 0 ) { error = "Image does not exist"; @@ -1006,6 +1013,8 @@ int ImageManager::delete_snapshot(int iid, int sid, string& error) imd->snapshot_delete(iid, *drv_msg); + img->set_state(Image::LOCKED); + ipool->update(img); img->unlock(); @@ -1030,6 +1039,13 @@ int ImageManager::revert_snapshot(int iid, int sid, string& error) return -1; } + /* ---------------------------------------------------------------------- */ + /* Check action consistency: */ + /* state is READY */ + /* snapshot exists */ + /* snapshot is not the active one */ + /* ---------------------------------------------------------------------- */ + Image * img = ipool->get(iid,true); if ( img == 0 ) @@ -1038,8 +1054,23 @@ int ImageManager::revert_snapshot(int iid, int sid, string& error) return -1; } + if (img->get_state() != Image::READY) + { + error = "Cannot revert to snapshot in state " + Image::state_to_str(img->get_state()); + img->unlock(); + return -1; + } + const Snapshots& snaps = img->get_snapshots(); + if (!snaps.exists(sid)) + { + error = "Snapshot does not exist"; + + img->unlock(); + return -1; + } + if (snaps.get_active_id() == sid) { error = "Snapshot is already the active one"; @@ -1048,6 +1079,9 @@ int ImageManager::revert_snapshot(int iid, int sid, string& error) return -1; } + /* ---------------------------------------------------------------------- */ + /* Get DS data for driver */ + /* ---------------------------------------------------------------------- */ int ds_id = img->get_ds_id(); img->unlock(); @@ -1066,6 +1100,9 @@ int ImageManager::revert_snapshot(int iid, int sid, string& error) ds->unlock(); + /* ---------------------------------------------------------------------- */ + /* Format message and send action to driver */ + /* ---------------------------------------------------------------------- */ img = ipool->get(iid,true); if ( img == 0 ) @@ -1076,11 +1113,13 @@ int ImageManager::revert_snapshot(int iid, int sid, string& error) img->set_target_snapshot(sid); - string img_tmpl; + string img_tmpl; string * drv_msg = format_message(img->to_xml(img_tmpl), ds_data); imd->snapshot_revert(iid, *drv_msg); + img->set_state(Image::LOCKED); + ipool->update(img); img->unlock(); diff --git a/src/image/ImageManagerDriver.cc b/src/image/ImageManagerDriver.cc index 9ca04e24e3..fa6dec4442 100644 --- a/src/image/ImageManagerDriver.cc +++ b/src/image/ImageManagerDriver.cc @@ -716,12 +716,16 @@ static void snap_delete_action(istringstream& is, return; } + image->set_state(Image::READY); + int snap_id = image->get_target_snapshot(); if (snap_id == -1) { NebulaLog::log("ImM", Log::ERROR, "No target snapshot in callback"); + ipool->update(image); + image->unlock(); return; } @@ -772,10 +776,14 @@ static void snap_revert_action(istringstream& is, int snap_id = image->get_target_snapshot(); + image->set_state(Image::READY); + if (snap_id == -1) { NebulaLog::log("ImM", Log::ERROR, "No target snapshot in callback"); + ipool->update(image); + image->unlock(); return; }