-
Notifications
You must be signed in to change notification settings - Fork 38.7k
wallet: improve error msg when db directory is not writable #34176
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
base: master
Are you sure you want to change the base?
Conversation
|
The following sections might be updated with supplementary metadata relevant to reviewers and maintainers. Code Coverage & BenchmarksFor details see: https://corecheck.dev/bitcoin/bitcoin/pulls/34176. ReviewsSee the guideline for information on the review process.
If your review is incorrectly listed, please copy-paste ConflictsReviewers, this pull request conflicts with the following ones:
If you consider this pull request important, please also help to review the conflicting pull requests. Ideally, start with the one that should be merged first. |
68a4677 to
16b82f1
Compare
rkrux
left a comment
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.
Combining the individual suggestions, the full diff:
diff --git a/test/functional/wallet_createwallet.py b/test/functional/wallet_createwallet.py
index 3bd8e6a310..f0b34d685d 100755
--- a/test/functional/wallet_createwallet.py
+++ b/test/functional/wallet_createwallet.py
@@ -33,21 +33,23 @@ class CreateWalletTest(BitcoinTestFramework):
wallet_name = "bad_permissions"
dir_path = node.wallets_path / wallet_name
dir_path.mkdir(parents=True)
- os.chmod(dir_path, stat.S_IREAD | stat.S_IEXEC)
+ original_dir_perms = dir_path.stat().st_mode
+ os.chmod(dir_path, original_dir_perms & ~(stat.S_IWUSR | stat.S_IWGRP | stat.S_IWOTH))
try:
- (dir_path / f".tmp_{random.randrange(1 << 32)}").touch() # Verify the directory is actually non-writable
- self.log.warn("Skipping non-writable directory test: unable to enforce read-only permissions")
- return
+ if (dir_path / f".tmp_{random.randrange(1 << 32)}").touch(): # Verify the directory is actually non-writable
+ self.log.warning("Skipping non-writable directory test: unable to enforce read-only permissions")
+ return
+ assert_raises_rpc_error(-4, f"SQLiteDatabase: Failed to open database in directory '{str(dir_path)}': directory is not writable", node.createwallet, wallet_name=wallet_name, descriptors=True)
except PermissionError:
pass
- assert_raises_rpc_error(-4, f"SQLiteDatabase: Failed to open database in directory '{str(dir_path)}': directory is not writable", node.createwallet, wallet_name=wallet_name, descriptors=True)
- dir_path.chmod(dir_path.stat().st_mode | stat.S_IWRITE)
+ finally:
+ dir_path.chmod(original_dir_perms)
c919a62 to
4ad08fc
Compare
|
Thanks for the review @rkrux! |
Add `IsDirWritable` helper in util/fs_helpers to test whether a directory can be written to by creating a temporary file. Use this check when opening a SQLite database to fail early with a clear error if the database directory is not writable, preventing obscure SQLite errors. Before: creating a wallet would throw a generic error: "SQLiteDatabase: Failed to open database: unable to open database file" After: creating a wallet throws: "SQLiteDatabase: Failed to open database in directory <dir_path>: directory is not writable"
4ad08fc to
0a9ddd3
Compare
|
Hmm. Nothing against better reporting when something failed, but the changes necessary to do that here seem a bit excessive for the pay-off? It doesn't seem like this change would have made resolving #34163 trivial? Didn't test, but would |
It turned out not to help with #34163, but it is a general improvement to reporting read-only permission issues. Which we currently don't do properly. Can take #34163 as the starting point that led to uncover other issues. Something I didn’t mention in the PR description is that this also fixes opening a non-writable wallet directory, which is actually more important than issues during creation. We currently open the wallet even when the directory is read-only, and then crash on any subsequent write because we cannot write to the Also, do you really think that labeling these changes as "excessive" is correct?
|
|
@stickies-v done. Run this simple test on master: furszy@85fa4e2 |
651eb90 to
66ebb96
Compare
Previously, wallets in non-writable directories were loaded, leading to crashes on any subsequent write.
66ebb96 to
2ef6add
Compare
It's not a big diff, but adding helper functions to improve diagnostic messages for a rare issue that is reasonably straightforward for the user to diagnose felt like perhaps not something we should have in our codebase, hence why I used "excessive" (in a relative way).
This seems like a much better rationale to me for this PR. Concept ACK. Approach-wise, I'm confused why the |
|
ACK 2ef6add Tests passed |
Make wallet creation and load fail with a clear error when the db directory isn’t writable.
1) For Wallet Creation
Before: creating a wallet would return a generic error:
"SQLiteDatabase: Failed to open database: unable to open database file"
After: creating a wallet returns:
"SQLiteDatabase: Failed to open database in directory <dir_path>: directory is not writable"
2) For Wallet Loading
We currently allow the load of wallets located on non-writable directories. This is problematic
because the node crashes on any subsequent write; generating a block is enough to trigger it.
Can be verified just by running the following test on master: furszy@85fa4e2
Also, to check directory writability, this creates a tmp file rather than relying on the
permissions()functions, since perms bits alone may not reliably reflect actual writabilityin some systems.
Testing Note:
Pushed the tests in separate commits so they can be cherry-picked on master for comparison.