-
Notifications
You must be signed in to change notification settings - Fork 306
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
DAOS-4120 md: pool create error cleanup on corpc send failure #2189
Conversation
With this change, when the management service while performing a pool create fails to send the MGMT_TGT_CREATE corpc to the pool storage target servers, the ds_mgmt_tgt_pool_destroy() function is called in the error handling path. It prevents the following problem. In rare cases when the dss_rpc_send() call fails (for example with -DER_TIMEDOUT because the target servers are under heavy load), the client will react to this timeout by retrying the pool create RPC with the same UUID. Because target resources have not been destroyed in the first attempt, this leads to a -DER_EXIST failure. Signed-off-by: Ken Cain <kenneth.c.cain@intel.com>
dfb21fd
to
a1faa8f
Compare
Cherry picked PR #2189 from daos master to release/0.9 branch. With this change, when the management service while performing a pool create fails to send the MGMT_TGT_CREATE corpc to the pool storage target servers, the ds_mgmt_tgt_pool_destroy() function is called in the error handling path. It prevents the following problem. In rare cases when the dss_rpc_send() call fails (for example with -DER_TIMEDOUT because the target servers are under heavy load), the client will react to this timeout by retrying the pool create RPC with the same UUID. Because target resources have not been destroyed in the first attempt, this leads to a -DER_EXIST failure. Signed-off-by: Ken Cain <kenneth.c.cain@intel.com>
Test stage run_test.sh completed with status FAILURE. https://build.hpdd.intel.com/job/daos-stack/job/daos/job/PR-2189/2/display/redirect |
Test stage run_test.sh completed with status FAILURE. https://build.hpdd.intel.com/job/daos-stack/job/daos/job/PR-2189/3/display/redirect |
Test stage run_test.sh completed with status FAILURE. https://build.hpdd.intel.com/job/daos-stack/job/daos/job/PR-2189/4/display/redirect |
The two test failures from build #6 appear to be instances of an already-bugged issue DAOS-4295 Random FIO test failures in master/PR runs. Test / Functional_Hardware_Medium / 1-./io/fio_small.py:FioSmall.test_fio_small;dfuse-bs_256B-sequential-test-hosts-pool-0-1-a417 – FioSmall |
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.
We probably need more complete way to make the whole process atomic. But this patch makes sense to me.
src/mgmt/srv_pool.c
Outdated
@@ -407,8 +407,11 @@ ds_mgmt_create_pool(uuid_t pool_uuid, const char *group, char *tgt_dev, | |||
if (rc == 0 && DAOS_FAIL_CHECK(DAOS_POOL_CREATE_FAIL_CORPC)) | |||
rc = -DER_TIMEDOUT; | |||
if (rc != 0) { | |||
if (!DAOS_FAIL_CHECK(DAOS_POOL_CREATE_FAIL_CORPC)) |
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.
Why do we not print the error when a fault has been injected?
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.
Maybe we should print the error message unconditionally (perhaps in a future commit). I thought it would be confusing if dss_rpc_send() actually succeeded and then print out an error message only because the code is injecting the fault after the fact.
If we print unconditinoally, do we care if for example there is a fault injection scenario (test expects to see -DER_TIMEDOUT), but the dss_rpc_send() also happens to actually fail with -DER_TIMEDOUT? No harm, or further confusion?
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.
Maybe we should print the error message unconditionally (perhaps in a future commit). I thought it would be confusing if dss_rpc_send() actually succeeded and then print out an error message only because the code is injecting the fault after the fact.
If we inject a fault, I think we usually expect error messages. (In one extreme, if the D_ERROR line would segfault due to a bug, the fault injection might have caught it.) Hence, I feel the error in this case is acceptable.
If we print unconditinoally, do we care if for example there is a fault injection scenario (test expects to see -DER_TIMEDOUT), but the dss_rpc_send() also happens to actually fail with -DER_TIMEDOUT? No harm, or further confusion?
I recall I had the same question when adding the fault injection. I first placed it before the dss_rpc_send call, but then realized that by placing it after the dss_rpc_send, I could simulate a CoRPC that succeeded on some targets before hitting a timeout. That might outweigh the confusion. Any better options?
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.
It's a bit nit-picking though, I admit.
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've updated the patch to make the error print unconditional
@daos-stack/daos-gatekeeper - as a convenience there is a companion PR for this change that is for the release/0.9 branch. Both can be landed at the same time if that helps reduce overhead. |
src/mgmt/srv_pool.c
Outdated
@@ -407,8 +407,11 @@ ds_mgmt_create_pool(uuid_t pool_uuid, const char *group, char *tgt_dev, | |||
if (rc == 0 && DAOS_FAIL_CHECK(DAOS_POOL_CREATE_FAIL_CORPC)) | |||
rc = -DER_TIMEDOUT; | |||
if (rc != 0) { | |||
if (!DAOS_FAIL_CHECK(DAOS_POOL_CREATE_FAIL_CORPC)) |
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.
Maybe we should print the error message unconditionally (perhaps in a future commit). I thought it would be confusing if dss_rpc_send() actually succeeded and then print out an error message only because the code is injecting the fault after the fact.
If we inject a fault, I think we usually expect error messages. (In one extreme, if the D_ERROR line would segfault due to a bug, the fault injection might have caught it.) Hence, I feel the error in this case is acceptable.
If we print unconditinoally, do we care if for example there is a fault injection scenario (test expects to see -DER_TIMEDOUT), but the dss_rpc_send() also happens to actually fail with -DER_TIMEDOUT? No harm, or further confusion?
I recall I had the same question when adding the fault injection. I first placed it before the dss_rpc_send call, but then realized that by placing it after the dss_rpc_send, I could simulate a CoRPC that succeeded on some targets before hitting a timeout. That might outweigh the confusion. Any better options?
Signed-off-by: Ken Cain <kenneth.c.cain@intel.com>
Test stage Functional_Hardware_Large completed with status UNSTABLE. https://build.hpdd.intel.com/job/daos-stack/job/daos//view/change-requests/job/PR-2189/7/testReport/(root)/ |
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.
Thanks.
Build 7 test failures:
Also, for release/0.9 branch PR-2195 is ready to land for this change. No test failures found in that PR's most recent build. |
Cherry picked PR #2189 from daos master to release/0.9 branch. With this change, when the management service while performing a pool create fails to send the MGMT_TGT_CREATE corpc to the pool storage target servers, the ds_mgmt_tgt_pool_destroy() function is called in the error handling path. It prevents the following problem. In rare cases when the dss_rpc_send() call fails (for example with -DER_TIMEDOUT because the target servers are under heavy load), the client will react to this timeout by retrying the pool create RPC with the same UUID. Because target resources have not been destroyed in the first attempt, this leads to a -DER_EXIST failure. Signed-off-by: Ken Cain <kenneth.c.cain@intel.com>
With this change, when the management service while performing a pool
create fails to send the MGMT_TGT_CREATE corpc to the pool storage
target servers, the ds_mgmt_tgt_pool_destroy() function is called in
the error handling path. It prevents the following problem.
In rare cases when the dss_rpc_send() call fails (for example with
-DER_TIMEDOUT because the target servers are under heavy load), the
client will react to this timeout by retrying the pool create RPC with
the same UUID. Because target resources have not been destroyed in the
first attempt, this leads to a -DER_EXIST failure.
Signed-off-by: Ken Cain kenneth.c.cain@intel.com