New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
librbd: asynchronous image removal state machine #12102
Conversation
348af7a
to
582fc1f
Compare
Seems it does not compile because there is some other dependent commits. Seems not difficult, Will address it tomorrow . |
anyone can help to add tags of rbd and feature? Thanx :) |
582fc1f
to
e8f1a96
Compare
@yangdongsheng @vshankar It looks like it needs some work -- see Jenkins failure. |
@trociny mostly yes -- probably due to changes in other parts of librbd. @yangdongsheng I can take a look at this next week but feel free to fix it! |
e8f1a96
to
24de125
Compare
[DNM] librbd: asynchronous image removal state machine #12102
@yangdongsheng @vshankar
|
[DNM] librbd: asynchronous image removal state machine #12102
src/librbd/image/RemoveRequest.cc
Outdated
ldout(m_cct, 20) << ": r=" << *result << dendl; | ||
|
||
if (*result < 0) { | ||
lderr(m_cct) << "error opening image: " << cpp_strerror(*result) << dendl; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I mean, the missing of m_retval assignment is definitely a bug. but why the journal and objectmap are not removed in RemoveRequest. @vshankar
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Oh, never mind. I found there is a step for disable features. These work would be done here. So I will fix the m_retval bug then.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@yangdongsheng Missing m_retval
assignment is definitely a bug, nothing intentional. While that needs to be fixed, make sure m_retval
is not clobbered again in handle_mirror_image_remove()
.
Journal and ObjectMap are removed -- see disable_features
which invokes DisableFeaturesRequest
state machine.
24de125
to
3b3ddcd
Compare
[DNM] librbd: asynchronous image removal state machine #12102
@yangdongsheng @vshankar This test from qa/workunits/rbd/copy.sh fails:
Now it returns:
|
@trociny When I look into more about the RemoveRequest, I think there are some more work we can do before merging it. So I propose we hold a while on this pull request. I will send a commit about my change about it for review, if that's okey, I will squash it into the original commit. Sounds good? @trociny @vshankar |
src/librbd/image/RemoveRequest.cc
Outdated
ldout(m_cct, 20) << ": r=" << *result << dendl; | ||
|
||
if ((*result < 0) && (*result != -ENOENT)) { | ||
if (m_retval == 0) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Seems like an unnecessary check. When we are here m_retval
is always -ve.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yes, it should be non-zero here. I added a check here just be sure we will not overwrite it. And make this function safe enough even when we move it to another locate in state machine.
That means, yes in this context, we don't need this block of code. But from the insight of making this function logically consistent. what about keep these code here?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
In that case, its good to put it up as a comment and keep the function without introducing changes which are not necessary now.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
comment sounds good. thanx
src/librbd/image/RemoveRequest.cc
Outdated
Context *RemoveRequest<I>::handle_mirror_image_remove(int *result) { | ||
ldout(m_cct, 20) << ": r=" << *result << dendl; | ||
|
||
if ((*result < 0) && (*result != -ENOENT)) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Please look at the original code. We need to check for -EOPNOTSUPP too, just in case we are running on an older cluster. Also, I don't like very much unnecessary extra parenthesis.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yes, correct, EOPNOTSUPP is important.
a440b58
to
056be49
Compare
056be49
to
9226525
Compare
@yangdongsheng It actually might just be an existing issue with the OpenStack tempest test case in how it handles cleanup [1]. |
@dillaman sounds yes. Thanx for your information. :) Then I think we can continue what we need on this PR. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
lgtm
retest this please |
@yangdongsheng there is a unit test failure with the latest re-build request |
@dillaman sounds like a race condition here.
So if the gc in c++ for the instance of owner_lock is after send_close_image(), this ceph_assert() could fail. Sounds possible? |
@yangdongsheng You should never assert on a lock not being held because another thread could always be using the lock in the background (in another thread). In the case of |
409bc0c
to
fed83ab
Compare
@dillaman thanx jason. updated as below:
|
@yangdongsheng Looks like the negative assert is still present and I hit it when I run the unit tests locally:
|
Signed-off-by: Dongsheng Yang <dongsheng.yang@easystack.cn>
Signed-off-by: Venky Shankar <vshankar@redhat.com>
Signed-off-by: Venky Shankar <vshankar@redhat.com>
Signed-off-by: Dongsheng Yang <dongsheng.yang@easystack.cn>
fed83ab
to
3ee9e3a
Compare
@dillaman there is a fix for it. And I tested it by hacking some code in trim to delay the releasing of owner_lock to reproduce the race condition.
|
src/librbd/image/RemoveRequest.cc
Outdated
ldout(m_cct, 20) << ": r=" << *result << dendl; | ||
|
||
{ | ||
// Wait the RLocker released in trim_image() |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I am not sure why this is even needed. librbd::image::CloseRequest
will eventually take a write-lock on ImageCtx::owner_lock
, so any potential for thread races should be cleared at that point long before the lock is destroyed. Did you ever hit a race where something failed because the trim request process was still holding a read-lock?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
After a second thought, I think there is no necessary for a assert at https://github.com/ceph/ceph/pull/12102/files#diff-7b8bedbcd26c203c38e02a5bd9dbfa1cR394 . This assert was moved from internal.cc which was a single-threading implementation. As you mentioned, CloseRequest will take the write-lock if they want. So we don't have to make sure the owner_lock is not hold outside. So fix as below:
--- a/src/librbd/image/RemoveRequest.cc
+++ b/src/librbd/image/RemoveRequest.cc
@@ -302,11 +302,6 @@ template<typename I>
Context *RemoveRequest<I>::handle_trim_image(int *result) {
ldout(m_cct, 20) << ": r=" << *result << dendl;
- {
- // Wait the RLocker released in trim_image()
- RWLock::WLocker owner_lock(m_image_ctx->owner_lock);
- }
-
if (*result < 0) {
lderr(m_cct) << "warning: failed to remove some object(s): " << cpp_strerror(*result)
<< dendl;
@@ -391,8 +386,6 @@ void RemoveRequest<I>::send_close_image(int r) {
ldout(m_cct, 20) << dendl;
m_ret_val = r;
- assert(!m_image_ctx->owner_lock.is_locked());
-
using klass = RemoveRequest<I>;
Context *ctx = create_context_callback<klass, &klass::handle_send_close_image>(this);
And I tested it by for ((i=0;i<100000;i++)); do CEPH_LIB=./lib ./bin/unittest_librbd --gtest_filter='TestMockImageRemoveRequest.*' >> /tmp/output; done; grep FAIL /tmp/output
with hacking this code:
--- a/src/librbd/image/RemoveRequest.cc
+++ b/src/librbd/image/RemoveRequest.cc
@@ -296,6 +296,11 @@ void RemoveRequest<I>::trim_image() {
librbd::operation::TrimRequest<I> *req = librbd::operation::TrimRequest<I>::create(
*m_image_ctx, ctx, m_image_ctx->size, 0, m_prog_ctx);
req->send();
+ int i = 0;
+ for (i = 0; i < 10000; i++) {
+ lderr(m_cct) << "delay delay delay the lock releasing: "
+ << dendl;
+ }
}
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@yangdongsheng just a hint: --gtest_repeat=1000000
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@trociny , Oh great!! thanx for your information. :)
Signed-off-by: Dongsheng Yang <dongsheng.yang@easystack.cn> Signed-off-by: Venky Shankar <vshankar@redhat.com>
Signed-off-by: Venky Shankar <vshankar@redhat.com>
Signed-off-by: Dongsheng Yang <dongsheng.yang@easystack.cn>
The copy.sh is not only testing the rbd copy, but also others such as rbd ls, rbd remove. Then rename it to generic.sh Signed-off-by: Dongsheng Yang <dongsheng.yang@easystack.cn>
Signed-off-by: Dongsheng Yang <dongsheng.yang@easystack.cn>
Signed-off-by: Dongsheng Yang <dongsheng.yang@easystack.cn>
Signed-off-by: Dongsheng Yang <dongsheng.yang@easystack.cn>
Signed-off-by: Dongsheng Yang <dongsheng.yang@easystack.cn>
Signed-off-by: Dongsheng Yang <dongsheng.yang@easystack.cn>
Signed-off-by: Dongsheng Yang <dongsheng.yang@easystack.cn>
Signed-off-by: Dongsheng Yang <dongsheng.yang@easystack.cn>
3ee9e3a
to
1077dbc
Compare
Thanx @vshankar give me the honor to open a separate Pull Request for Async remove state machine. This will be referred by #10896 and #12041