X-Git-Url: https://gerrit.opnfv.org/gerrit/gitweb?a=blobdiff_plain;f=src%2Fceph%2Fsrc%2Flibrbd%2Foperation%2FDisableFeaturesRequest.cc;fp=src%2Fceph%2Fsrc%2Flibrbd%2Foperation%2FDisableFeaturesRequest.cc;h=0000000000000000000000000000000000000000;hb=7da45d65be36d36b880cc55c5036e96c24b53f00;hp=34cc9579fe84567a41fdf6c7cd4a400cc6dfddbc;hpb=691462d09d0987b47e112d6ee8740375df3c51b2;p=stor4nfv.git diff --git a/src/ceph/src/librbd/operation/DisableFeaturesRequest.cc b/src/ceph/src/librbd/operation/DisableFeaturesRequest.cc deleted file mode 100644 index 34cc957..0000000 --- a/src/ceph/src/librbd/operation/DisableFeaturesRequest.cc +++ /dev/null @@ -1,642 +0,0 @@ -// -*- mode:C++; tab-width:8; c-basic-offset:2; indent-tabs-mode:t -*- -// vim: ts=8 sw=2 smarttab - -#include "librbd/operation/DisableFeaturesRequest.h" -#include "common/dout.h" -#include "common/errno.h" -#include "cls/rbd/cls_rbd_client.h" -#include "librbd/ExclusiveLock.h" -#include "librbd/ImageCtx.h" -#include "librbd/ImageState.h" -#include "librbd/Journal.h" -#include "librbd/Utils.h" -#include "librbd/image/SetFlagsRequest.h" -#include "librbd/io/ImageRequestWQ.h" -#include "librbd/journal/RemoveRequest.h" -#include "librbd/mirror/DisableRequest.h" -#include "librbd/object_map/RemoveRequest.h" - -#define dout_subsys ceph_subsys_rbd -#undef dout_prefix -#define dout_prefix *_dout << "librbd::DisableFeaturesRequest: " - -namespace librbd { -namespace operation { - -using util::create_async_context_callback; -using util::create_context_callback; -using util::create_rados_callback; - -template -DisableFeaturesRequest::DisableFeaturesRequest(I &image_ctx, - Context *on_finish, - uint64_t journal_op_tid, - uint64_t features, - bool force) - : Request(image_ctx, on_finish, journal_op_tid), m_features(features), - m_force(force) { -} - -template -void DisableFeaturesRequest::send_op() { - I &image_ctx = this->m_image_ctx; - CephContext *cct = image_ctx.cct; - assert(image_ctx.owner_lock.is_locked()); - - ldout(cct, 20) << this << " " << __func__ << ": features=" << m_features - << dendl; - - send_prepare_lock(); -} - -template -bool DisableFeaturesRequest::should_complete(int r) { - I &image_ctx = this->m_image_ctx; - CephContext *cct = image_ctx.cct; - ldout(cct, 20) << this << " " << __func__ << "r=" << r << dendl; - - if (r < 0) { - lderr(cct) << "encountered error: " << cpp_strerror(r) << dendl; - } - return true; -} - -template -void DisableFeaturesRequest::send_prepare_lock() { - I &image_ctx = this->m_image_ctx; - CephContext *cct = image_ctx.cct; - ldout(cct, 20) << this << " " << __func__ << dendl; - - image_ctx.state->prepare_lock(create_async_context_callback( - image_ctx, create_context_callback< - DisableFeaturesRequest, - &DisableFeaturesRequest::handle_prepare_lock>(this))); -} - -template -Context *DisableFeaturesRequest::handle_prepare_lock(int *result) { - I &image_ctx = this->m_image_ctx; - CephContext *cct = image_ctx.cct; - ldout(cct, 20) << this << " " << __func__ << ": r=" << *result << dendl; - - if (*result < 0) { - lderr(cct) << "failed to lock image: " << cpp_strerror(*result) << dendl; - return this->create_context_finisher(*result); - } - - send_block_writes(); - return nullptr; -} - -template -void DisableFeaturesRequest::send_block_writes() { - I &image_ctx = this->m_image_ctx; - CephContext *cct = image_ctx.cct; - ldout(cct, 20) << this << " " << __func__ << dendl; - - RWLock::WLocker locker(image_ctx.owner_lock); - image_ctx.io_work_queue->block_writes(create_context_callback< - DisableFeaturesRequest, - &DisableFeaturesRequest::handle_block_writes>(this)); -} - -template -Context *DisableFeaturesRequest::handle_block_writes(int *result) { - I &image_ctx = this->m_image_ctx; - CephContext *cct = image_ctx.cct; - ldout(cct, 20) << this << " " << __func__ << ": r=" << *result << dendl; - - if (*result < 0) { - lderr(cct) << "failed to block writes: " << cpp_strerror(*result) << dendl; - return handle_finish(*result); - } - m_writes_blocked = true; - - { - RWLock::WLocker locker(image_ctx.owner_lock); - // avoid accepting new requests from peers while we manipulate - // the image features - if (image_ctx.exclusive_lock != nullptr && - (image_ctx.journal == nullptr || - !image_ctx.journal->is_journal_replaying())) { - image_ctx.exclusive_lock->block_requests(0); - m_requests_blocked = true; - } - } - - send_acquire_exclusive_lock(); - return nullptr; -} - -template -void DisableFeaturesRequest::send_acquire_exclusive_lock() { - I &image_ctx = this->m_image_ctx; - CephContext *cct = image_ctx.cct; - ldout(cct, 20) << this << " " << __func__ << dendl; - - Context *ctx = create_context_callback< - DisableFeaturesRequest, - &DisableFeaturesRequest::handle_acquire_exclusive_lock>(this); - - { - RWLock::WLocker locker(image_ctx.owner_lock); - // if disabling features w/ exclusive lock supported, we need to - // acquire the lock to temporarily block IO against the image - if (image_ctx.exclusive_lock != nullptr && - !image_ctx.exclusive_lock->is_lock_owner()) { - m_acquired_lock = true; - - image_ctx.exclusive_lock->acquire_lock(ctx); - return; - } - } - - ctx->complete(0); -} - -template -Context *DisableFeaturesRequest::handle_acquire_exclusive_lock(int *result) { - I &image_ctx = this->m_image_ctx; - CephContext *cct = image_ctx.cct; - ldout(cct, 20) << this << " " << __func__ << ": r=" << *result << dendl; - - if (*result < 0) { - lderr(cct) << "failed to lock image: " << cpp_strerror(*result) << dendl; - return handle_finish(*result); - } else if (m_acquired_lock && (image_ctx.exclusive_lock == nullptr || - !image_ctx.exclusive_lock->is_lock_owner())) { - lderr(cct) << "failed to acquire exclusive lock" << dendl; - *result = -EROFS; - return handle_finish(*result); - } - - do { - RWLock::WLocker locker(image_ctx.owner_lock); - - m_features &= image_ctx.features; - m_new_features = image_ctx.features & ~m_features; - m_features_mask = m_features; - - if ((m_features & RBD_FEATURE_EXCLUSIVE_LOCK) != 0) { - if ((m_new_features & RBD_FEATURE_OBJECT_MAP) != 0 || - (m_new_features & RBD_FEATURE_JOURNALING) != 0) { - lderr(cct) << "cannot disable exclusive-lock. object-map " - "or journaling must be disabled before " - "disabling exclusive-lock." << dendl; - *result = -EINVAL; - break; - } - m_features_mask |= (RBD_FEATURE_OBJECT_MAP | - RBD_FEATURE_JOURNALING); - } - if ((m_features & RBD_FEATURE_FAST_DIFF) != 0) { - m_disable_flags |= RBD_FLAG_FAST_DIFF_INVALID; - } - if ((m_features & RBD_FEATURE_OBJECT_MAP) != 0) { - if ((m_new_features & RBD_FEATURE_FAST_DIFF) != 0) { - lderr(cct) << "cannot disable object-map. fast-diff must be " - "disabled before disabling object-map." << dendl; - *result = -EINVAL; - break; - } - m_disable_flags |= RBD_FLAG_OBJECT_MAP_INVALID; - } - } while (false); - - if (*result < 0) { - return handle_finish(*result); - } - - send_get_mirror_mode(); - return nullptr; -} - -template -void DisableFeaturesRequest::send_get_mirror_mode() { - I &image_ctx = this->m_image_ctx; - CephContext *cct = image_ctx.cct; - - if ((m_features & RBD_FEATURE_JOURNALING) == 0) { - send_append_op_event(); - return; - } - - ldout(cct, 20) << this << " " << __func__ << dendl; - - librados::ObjectReadOperation op; - cls_client::mirror_mode_get_start(&op); - - using klass = DisableFeaturesRequest; - librados::AioCompletion *comp = - create_rados_callback(this); - m_out_bl.clear(); - int r = image_ctx.md_ctx.aio_operate(RBD_MIRRORING, comp, &op, &m_out_bl); - assert(r == 0); - comp->release(); -} - -template -Context *DisableFeaturesRequest::handle_get_mirror_mode(int *result) { - I &image_ctx = this->m_image_ctx; - CephContext *cct = image_ctx.cct; - ldout(cct, 20) << this << " " << __func__ << ": r=" << *result << dendl; - - if (*result == 0) { - bufferlist::iterator it = m_out_bl.begin(); - *result = cls_client::mirror_mode_get_finish(&it, &m_mirror_mode); - } - - if (*result < 0 && *result != -ENOENT) { - lderr(cct) << "failed to retrieve pool mirror mode: " - << cpp_strerror(*result) << dendl; - return handle_finish(*result); - } - - ldout(cct, 20) << this << " " << __func__ << ": m_mirror_mode=" - << m_mirror_mode << dendl; - - send_get_mirror_image(); - return nullptr; -} - -template -void DisableFeaturesRequest::send_get_mirror_image() { - I &image_ctx = this->m_image_ctx; - CephContext *cct = image_ctx.cct; - - if (m_mirror_mode != cls::rbd::MIRROR_MODE_IMAGE) { - send_disable_mirror_image(); - return; - } - - ldout(cct, 20) << this << " " << __func__ << dendl; - - librados::ObjectReadOperation op; - cls_client::mirror_image_get_start(&op, image_ctx.id); - - using klass = DisableFeaturesRequest; - librados::AioCompletion *comp = - create_rados_callback(this); - m_out_bl.clear(); - int r = image_ctx.md_ctx.aio_operate(RBD_MIRRORING, comp, &op, &m_out_bl); - assert(r == 0); - comp->release(); -} - -template -Context *DisableFeaturesRequest::handle_get_mirror_image(int *result) { - I &image_ctx = this->m_image_ctx; - CephContext *cct = image_ctx.cct; - ldout(cct, 20) << this << " " << __func__ << dendl; - - cls::rbd::MirrorImage mirror_image; - - if (*result == 0) { - bufferlist::iterator it = m_out_bl.begin(); - *result = cls_client::mirror_image_get_finish(&it, &mirror_image); - } - - if (*result < 0 && *result != -ENOENT) { - lderr(cct) << "failed to retrieve pool mirror image: " - << cpp_strerror(*result) << dendl; - return handle_finish(*result); - } - - if ((mirror_image.state == cls::rbd::MIRROR_IMAGE_STATE_ENABLED) && !m_force) { - lderr(cct) << "cannot disable journaling: image mirroring " - << "enabled and mirror pool mode set to image" - << dendl; - *result = -EINVAL; - return handle_finish(*result); - } - - send_disable_mirror_image(); - return nullptr; -} - -template -void DisableFeaturesRequest::send_disable_mirror_image() { - I &image_ctx = this->m_image_ctx; - CephContext *cct = image_ctx.cct; - - ldout(cct, 20) << this << " " << __func__ << dendl; - - Context *ctx = create_context_callback< - DisableFeaturesRequest, - &DisableFeaturesRequest::handle_disable_mirror_image>(this); - - mirror::DisableRequest *req = - mirror::DisableRequest::create(&image_ctx, m_force, true, ctx); - req->send(); -} - -template -Context *DisableFeaturesRequest::handle_disable_mirror_image(int *result) { - I &image_ctx = this->m_image_ctx; - CephContext *cct = image_ctx.cct; - ldout(cct, 20) << this << " " << __func__ << ": r=" << *result << dendl; - - if (*result < 0) { - lderr(cct) << "failed to disable image mirroring: " << cpp_strerror(*result) - << dendl; - // not fatal - } - - send_close_journal(); - return nullptr; -} - -template -void DisableFeaturesRequest::send_close_journal() { - I &image_ctx = this->m_image_ctx; - CephContext *cct = image_ctx.cct; - - { - RWLock::WLocker locker(image_ctx.owner_lock); - if (image_ctx.journal != nullptr) { - ldout(cct, 20) << this << " " << __func__ << dendl; - - std::swap(m_journal, image_ctx.journal); - Context *ctx = create_context_callback< - DisableFeaturesRequest, - &DisableFeaturesRequest::handle_close_journal>(this); - - m_journal->close(ctx); - return; - } - } - - send_remove_journal(); -} - -template -Context *DisableFeaturesRequest::handle_close_journal(int *result) { - I &image_ctx = this->m_image_ctx; - CephContext *cct = image_ctx.cct; - ldout(cct, 20) << this << " " << __func__ << ": r=" << *result << dendl; - - if (*result < 0) { - lderr(cct) << "failed to close image journal: " << cpp_strerror(*result) - << dendl; - } - - assert(m_journal != nullptr); - delete m_journal; - m_journal = nullptr; - - send_remove_journal(); - return nullptr; -} - -template -void DisableFeaturesRequest::send_remove_journal() { - I &image_ctx = this->m_image_ctx; - CephContext *cct = image_ctx.cct; - ldout(cct, 20) << this << " " << __func__ << dendl; - - Context *ctx = create_context_callback< - DisableFeaturesRequest, - &DisableFeaturesRequest::handle_remove_journal>(this); - - journal::RemoveRequest *req = journal::RemoveRequest::create( - image_ctx.md_ctx, image_ctx.id, librbd::Journal<>::IMAGE_CLIENT_ID, - image_ctx.op_work_queue, ctx); - - req->send(); -} - -template -Context *DisableFeaturesRequest::handle_remove_journal(int *result) { - I &image_ctx = this->m_image_ctx; - CephContext *cct = image_ctx.cct; - ldout(cct, 20) << this << " " << __func__ << ": r=" << *result << dendl; - - if (*result < 0) { - lderr(cct) << "failed to remove image journal: " << cpp_strerror(*result) - << dendl; - return handle_finish(*result); - } - - send_append_op_event(); - return nullptr; -} - -template -void DisableFeaturesRequest::send_append_op_event() { - I &image_ctx = this->m_image_ctx; - CephContext *cct = image_ctx.cct; - - if (!this->template append_op_event< - DisableFeaturesRequest, - &DisableFeaturesRequest::handle_append_op_event>(this)) { - send_remove_object_map(); - } - - ldout(cct, 20) << this << " " << __func__ << dendl; -} - -template -Context *DisableFeaturesRequest::handle_append_op_event(int *result) { - I &image_ctx = this->m_image_ctx; - CephContext *cct = image_ctx.cct; - ldout(cct, 20) << this << " " << __func__ << ": r=" << *result << dendl; - - if (*result < 0) { - lderr(cct) << "failed to commit journal entry: " << cpp_strerror(*result) - << dendl; - return handle_finish(*result); - } - - send_remove_object_map(); - return nullptr; -} - -template -void DisableFeaturesRequest::send_remove_object_map() { - I &image_ctx = this->m_image_ctx; - CephContext *cct = image_ctx.cct; - ldout(cct, 20) << this << " " << __func__ << dendl; - - if ((m_features & RBD_FEATURE_OBJECT_MAP) == 0) { - send_set_features(); - return; - } - - Context *ctx = create_context_callback< - DisableFeaturesRequest, - &DisableFeaturesRequest::handle_remove_object_map>(this); - - object_map::RemoveRequest *req = - object_map::RemoveRequest::create(&image_ctx, ctx); - req->send(); -} - -template -Context *DisableFeaturesRequest::handle_remove_object_map(int *result) { - I &image_ctx = this->m_image_ctx; - CephContext *cct = image_ctx.cct; - ldout(cct, 20) << this << " " << __func__ << ": r=" << *result << dendl; - - if (*result < 0) { - lderr(cct) << "failed to remove object map: " << cpp_strerror(*result) << dendl; - return handle_finish(*result); - } - - send_set_features(); - return nullptr; -} - -template -void DisableFeaturesRequest::send_set_features() { - I &image_ctx = this->m_image_ctx; - CephContext *cct = image_ctx.cct; - ldout(cct, 20) << this << " " << __func__ << ": new_features=" - << m_new_features << ", features_mask=" << m_features_mask - << dendl; - - librados::ObjectWriteOperation op; - librbd::cls_client::set_features(&op, m_new_features, m_features_mask); - - using klass = DisableFeaturesRequest; - librados::AioCompletion *comp = - create_rados_callback(this); - int r = image_ctx.md_ctx.aio_operate(image_ctx.header_oid, comp, &op); - assert(r == 0); - comp->release(); -} - -template -Context *DisableFeaturesRequest::handle_set_features(int *result) { - I &image_ctx = this->m_image_ctx; - CephContext *cct = image_ctx.cct; - ldout(cct, 20) << this << " " << __func__ << ": r=" << *result << dendl; - - if (*result == -EINVAL && (m_features_mask & RBD_FEATURE_JOURNALING) != 0) { - // NOTE: infernalis OSDs will not accept a mask with new features, so - // re-attempt with a reduced mask. - ldout(cct, 5) << this << " " << __func__ - << ": re-attempt with a reduced mask" << dendl; - m_features_mask &= ~RBD_FEATURE_JOURNALING; - send_set_features(); - } - - if (*result < 0) { - lderr(cct) << "failed to update features: " << cpp_strerror(*result) - << dendl; - return handle_finish(*result); - } - - send_update_flags(); - return nullptr; -} - -template -void DisableFeaturesRequest::send_update_flags() { - I &image_ctx = this->m_image_ctx; - CephContext *cct = image_ctx.cct; - - if (m_disable_flags == 0) { - send_notify_update(); - return; - } - - ldout(cct, 20) << this << " " << __func__ << ": disable_flags=" - << m_disable_flags << dendl; - - Context *ctx = create_context_callback< - DisableFeaturesRequest, - &DisableFeaturesRequest::handle_update_flags>(this); - - image::SetFlagsRequest *req = - image::SetFlagsRequest::create(&image_ctx, 0, m_disable_flags, ctx); - req->send(); -} - -template -Context *DisableFeaturesRequest::handle_update_flags(int *result) { - I &image_ctx = this->m_image_ctx; - CephContext *cct = image_ctx.cct; - ldout(cct, 20) << this << " " << __func__ << ": r=" << *result << dendl; - - if (*result < 0) { - lderr(cct) << "failed to update image flags: " << cpp_strerror(*result) - << dendl; - return handle_finish(*result); - } - - send_notify_update(); - return nullptr; -} - -template -void DisableFeaturesRequest::send_notify_update() { - I &image_ctx = this->m_image_ctx; - CephContext *cct = image_ctx.cct; - ldout(cct, 20) << this << " " << __func__ << dendl; - - Context *ctx = create_context_callback< - DisableFeaturesRequest, - &DisableFeaturesRequest::handle_notify_update>(this); - - image_ctx.notify_update(ctx); -} - -template -Context *DisableFeaturesRequest::handle_notify_update(int *result) { - I &image_ctx = this->m_image_ctx; - CephContext *cct = image_ctx.cct; - ldout(cct, 20) << this << " " << __func__ << ": r=" << *result << dendl; - - if (image_ctx.exclusive_lock == nullptr || !m_acquired_lock) { - return handle_finish(*result); - } - - send_release_exclusive_lock(); - return nullptr; -} - -template -void DisableFeaturesRequest::send_release_exclusive_lock() { - I &image_ctx = this->m_image_ctx; - CephContext *cct = image_ctx.cct; - ldout(cct, 20) << this << " " << __func__ << dendl; - - Context *ctx = create_context_callback< - DisableFeaturesRequest, - &DisableFeaturesRequest::handle_release_exclusive_lock>(this); - - image_ctx.exclusive_lock->release_lock(ctx); -} - -template -Context *DisableFeaturesRequest::handle_release_exclusive_lock(int *result) { - I &image_ctx = this->m_image_ctx; - CephContext *cct = image_ctx.cct; - ldout(cct, 20) << this << " " << __func__ << ": r=" << *result << dendl; - - return handle_finish(*result); -} - -template -Context *DisableFeaturesRequest::handle_finish(int r) { - I &image_ctx = this->m_image_ctx; - CephContext *cct = image_ctx.cct; - ldout(cct, 20) << this << " " << __func__ << ": r=" << r << dendl; - - { - RWLock::WLocker locker(image_ctx.owner_lock); - if (image_ctx.exclusive_lock != nullptr && m_requests_blocked) { - image_ctx.exclusive_lock->unblock_requests(); - } - - image_ctx.io_work_queue->unblock_writes(); - } - image_ctx.state->handle_prepare_lock_complete(); - - return this->create_context_finisher(r); -} - -} // namespace operation -} // namespace librbd - -template class librbd::operation::DisableFeaturesRequest;