-
Notifications
You must be signed in to change notification settings - Fork 51
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
broker: fix content-cache flush list corruption #4484
broker: fix content-cache flush list corruption #4484
Conversation
nit for debate: is "corruption" the right word to use here for comments / commit messages / descriptions? Lets say we got a list like:
lets say
b/c code would set it's not really "corrupted" in the usual sense of the word, but I couldn't think of a better one. Like just "damaged"? |
hmmm, one builder failed my regression test b/c of:
not sure why every other builder works. Lemme try using |
Well first, excellent job tracking this down, and it seems like the effect is actually pretty insidious. Here's a thought. In at least one other place In content-cache.c, I see we call list_del_from (&cache->lru, &e->list);
list_add (&cache->lru, &e->list); would doing that be sufficient rather than creating a new If we need to add a new function, we may want to add it directly to libccan and submit the change upstream. Or if it's really only useful to us, then possibly add it with a "namespace" other than "list_" so it is evident to casual perusers of our code that it's not part of the original class. But if we can do something simple to use the class as designed without adding anything then maybe it's better to do that. |
Hmmm, I don't think that will specifically work b/c it requires the entry to be on a list already (there's an assert in the ccan code that checks for this fact). but
I went down this path just b/c I remember needing the check in the KVS. But doing something similar to what you suggested should be fine. |
7d9d663
to
f904744
Compare
re-pushed, doing |
f904744
to
b15711f
Compare
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. Thanks, simple is good.
Just a suggestion for improving the test.
flux kvs put issue4482A.a="abcdefghijk" | ||
flux kvs put issue4482A.b="lmnopqrstuv" | ||
flux kvs put issue4482A.c="wxyz0123456" | ||
flux kvs put issue4482A.d="7890ABCDEFG" | ||
flux kvs put issue4482A.e="HIJKLMNOPQR" | ||
flux kvs put issue4482A.f="STUVWXYZ!!!" | ||
flux kvs put issue4482A.g="<<<<<:>>>>>" | ||
|
||
flux kvs dropcache | ||
|
||
flux kvs put issue4482B.a="abcdefghijk" | ||
flux kvs put issue4482B.b="lmnopqrstuv" | ||
flux kvs put issue4482B.c="wxyz0123456" | ||
flux kvs put issue4482B.d="7890ABCDEFG" | ||
flux kvs put issue4482B.e="HIJKLMNOPQR" | ||
flux kvs put issue4482B.f="STUVWXYZ!!!" |
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'm not sure this is doing what it looks like at face value, although it still may work. Those short values will be cached inside the directory entry for "issue4482B" so really what you're doing is creating multiple versions of that directory and the root in the content store.
Suggestion: use flux content store
since the problem this pokes at has nothing to do with the kvs.
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.
ahhh yeah, you're right my description is not correct, but I the the effect is identical, the multiple versions of the directory are the "data", not the junk I'm writing.
Let me try with flux content store
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.
Not a full review, but I did want to point something out in how the test is organized.
Also, in practice we usually split additional tests into a separate commit (unless code changes break tests) in keeping with the idea that commits should "do one thing". However, I don't feel strongly about that so this is fine with me.
|
||
chmod +x t4482.sh | ||
|
||
flux start -s 1 \ |
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.
Since the test script is generated in place, it might be easier (and keep all test components together) to generate the custom rc1
and rc3
scripts here as well. I'd also hate to proliferate the one-off rc scripts in t/rc
and end up with many rc1-issue*
files in there in the future.
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.
Or, you could do away with the rc scripts and just load and unload necessary modules directly in the test script as you are doing with content-sqlite
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.
My vote would be to make the test self-contained as well. It should probably drop the bash -e option and handle errors explicitly then, so that it doesn't bail out leaving modules unloaded for the next test.
Problem: A dirty cache entry has to potential to be added onto the content cache's flush list twice. This double addition can lead to list corruption. The observed side effect was a list that was shortened and no longer accurate with respect to the `acct_dirty` counter. This could lead to hangs with content flush, missed flushes to the backing store, and segfault/memory corruption in the worst case. Solution: Remove the cache entry from the flush list before adding it. The remove is a no-op if it is not already on a list. Fixes flux-framework#4482
Problem: No test covers duplicate content cache entries being added to the content cache's flush list. Solution: Add a regression test.
b15711f
to
8c51d6f
Compare
re-pushed, cleaned up the test a ton, it looks far simpler / better now, and split it off into its own commit. |
Codecov Report
@@ Coverage Diff @@
## master #4484 +/- ##
==========================================
- Coverage 83.37% 83.37% -0.01%
==========================================
Files 401 401
Lines 67527 67529 +2
==========================================
- Hits 56303 56301 -2
- Misses 11224 11228 +4
|
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!
Problem: It would be nice to get a simple answer of what nodes/ranks are up vs down in the overlay network. Solution: Support a new flux overlay whatsup subcommand that is modeled after the whatsup(1) command. Fixes flux-framework#4484
Problem: It would be nice to get a simple answer of what nodes/ranks are up vs down in the overlay network. Solution: Support a new flux overlay whatsup subcommand that is modeled after the whatsup(1) command. Fixes flux-framework#4484
Problem: It would be nice to get a simple answer of what nodes/ranks are up vs down in the overlay network. Solution: Support a new flux overlay whatsup subcommand that is modeled after the whatsup(1) command. Fixes flux-framework#4484
Problem: A dirty cache entry has to potential to be added onto the flush list twice. This double addition can lead to list corruption.
The observed side effect was a list that was shortened and no longer accurate with respects to the
acct_dirty
counter. This could lead to hangs with content flush, missed flushes to the backing store, and segfault/memory corruption in the worst case.Solution: Check if the cache entry is already on the flush list before adding it.
Fixes #4482