init: Lock blocksdir in addition to datadir #31674

pull theuni wants to merge 4 commits into bitcoin:master from theuni:lock-blocksdir changing 6 files +46 −24
  1. theuni commented at 3:58 pm on January 16, 2025: member

    This probably should’ve been included in #12653 when -blocksdir was introduced. Credit TheCharlatan for noticing that it’s missing.

    This guards against 2 processes running with separate datadirs but the same blocksdir. I didn’t add walletdir as I assume sqlite has us covered there.

    It’s not likely to happen currently, but may be more relevant in the future with applications using the kernel. Note that the kernel does not currently do any dir locking, but it should.

  2. DrahtBot commented at 3:58 pm on January 16, 2025: contributor

    The following sections might be updated with supplementary metadata relevant to reviewers and maintainers.

    Code Coverage & Benchmarks

    For details see: https://corecheck.dev/bitcoin/bitcoin/pulls/31674.

    Reviews

    See the guideline for information on the review process.

    Type Reviewers
    ACK tdb3, maflcko
    Concept ACK davidgumberg, hebasto, BrandonOdiwuor

    If your review is incorrectly listed, please react with 👎 to this comment and the bot will ignore it on the next update.

  3. DrahtBot added the label CI failed on Jan 16, 2025
  4. theuni commented at 6:06 pm on January 16, 2025: member
    This caused an incompatibility with blocksdirs from previous versions of Core. Setting to draft whlie I play around with a fix.
  5. theuni marked this as a draft on Jan 16, 2025
  6. init: allow a new xor key to be written if the blocksdir is newly created
    A subsequent commit will add a .lock file to this dir at startup, meaning that
    the blocksdir is never empty by the time the xor key is being read/written.
    
    Ignore all hidden files when determining if this is the first run.
    1db331ba76
  7. refactor: introduce a more general LockDirectories for init
    No functional change. This is in preparation for adding additional directory
    locks on startup.
    cabb2e5c24
  8. init: lock blocksdir in addition to datadir
    This guards against 2 processes running with separate datadirs but the same
    blocksdir.
    
    It's not likely to happen currently, but may be more relevant in the future
    with applications using the kernel.
    
    Note that the kernel does not currently do any dir locking, but it should.
    bdc0a68e67
  9. tests: add a test for the new blocksdir lock 2656a5658c
  10. in src/node/blockstorage.cpp:1146 in a8d2fd4141 outdated
    1147-        // Only use random fresh key when the boolean option is set and on the
    1148-        // very first start of the program.
    1149-        FastRandomContext{}.fillrand(xor_key);
    1150-    }
    1151-
    1152+    const fs::path xor_feature_path{opts.blocks_dir / ".feature_xor"};
    


    maflcko commented at 7:38 pm on January 16, 2025:
    I guess it is fine to ignore any “hidden” files (starting with .) as an alternative.

    theuni commented at 8:34 pm on January 16, 2025:

    Ideally the xor key would be written at the time of blocksdir creation. But I had a go at that and it means that non-bitcoind (kernel, tests, etc) binaries wouldn’t get a key written.

    So yeah, filtering it out here is probably the most straightforward. Blah.


    theuni commented at 9:25 pm on January 16, 2025:
    Done.
  11. theuni force-pushed on Jan 16, 2025
  12. DrahtBot removed the label CI failed on Jan 17, 2025
  13. davidgumberg commented at 1:51 am on January 17, 2025: contributor
    Concept ACK
  14. hebasto commented at 9:17 am on January 17, 2025: member
    Concept ACK.
  15. in src/node/blockstorage.cpp:1156 in 2656a5658c
    1152+        const std::string path = fs::PathToString(entry.path().filename());
    1153+        if (!entry.is_regular_file() || !path.starts_with('.')) {
    1154+            first_run = false;
    1155+            break;
    1156+        }
    1157+    }
    


    maflcko commented at 10:08 am on January 17, 2025:

    style nit: Could use ranges, if you feel fancy :sweat_smile:

    0bool first_run = std::ranges::all_of(
    1    fs::directory_iterator(opts.blocks_dir),
    2    [](const auto& entry) {
    3        const std::string path = fs::PathToString(entry.path().filename());
    4        return entry.is_regular_file() && path.starts_with('.');
    5    }
    6);
    

    theuni commented at 8:11 pm on January 17, 2025:
    I’d rather stay old-school unless you have a strong preference :)

    maflcko commented at 8:50 am on January 20, 2025:
    I suggested it, because it avoids the two negations and it is shorter, so it reads more natural, at least to me. But it is just a nit.
  16. in src/init.cpp:1089 in bdc0a68e67 outdated
    1085@@ -1086,7 +1086,8 @@ static bool LockDirectory(const fs::path& dir, bool probeOnly)
    1086 }
    1087 static bool LockDirectories(bool probeOnly)
    1088 {
    1089-    return LockDirectory(gArgs.GetDataDirNet(), probeOnly);
    1090+    return LockDirectory(gArgs.GetDataDirNet(), probeOnly) && \
    


    maflcko commented at 10:16 am on January 17, 2025:
    nit in bdc0a68e676f237bcbb5195a60bb08bb34123e71: Could run clang-format on new code to remove the stray \?
  17. in test/functional/feature_filelock.py:40 in 2656a5658c
    36         self.nodes[1].assert_start_raises_init_error(extra_args=[f'-datadir={self.nodes[0].datadir_path}', '-noserver'], expected_msg=expected_msg)
    37 
    38-        self.log.info("Check that cookie and PID file are not deleted when attempting to start a second bitcoind using the same datadir")
    39+        self.log.info("Check that we can't start a second bitcoind instance using the same blocksdir")
    40+        expected_msg = f"Error: Cannot obtain a lock on directory {blocksdir}. {self.config['environment']['CLIENT_NAME']} is probably already running."
    41+        self.nodes[1].assert_start_raises_init_error(extra_args=[f'-blocksdir={self.nodes[0].datadir_path}', '-noserver'], expected_msg=expected_msg)
    


    maflcko commented at 10:21 am on January 17, 2025:
    2656a5658c14b43c32959db7235e9db55a17d4c8: Any reason to pass the datadir_path as the blocksdir?

    theuni commented at 8:08 pm on January 17, 2025:
    The arg that blocksdir takes is actually the profiledir which contains the blocks dir, not the blocks dir itself. So passing blocksdir=datadir here means “use my own datadir but node0’s blocksdir”, which is what this test intends to cover. Unless I’m missing something?

    maflcko commented at 8:50 am on January 20, 2025:
    Sorry, I completely mis-read the test in the last commit. All good, please resolve.
  18. maflcko commented at 10:22 am on January 17, 2025: member

    lgtm, but I left a question in the test commit and didn’t check it further.

    review ACK 2656a5658c14b43c32959db7235e9db55a17d4c8 🏼

    Signature:

    0untrusted comment: signature from minisign secret key on empty file; verify via: minisign -Vm "${path_to_any_empty_file}" -P RWTRmVTMeKV5noAMqVlsMugDDCyyTSbA3Re5AkUrhvLVln0tSaFWglOw -x "${path_to_this_whole_four_line_signature_blob}"
    1RUTRmVTMeKV5npGrKx1nqXCw5zeVHdtdYURB/KlyA/LMFgpNCs+SkW9a8N95d+U4AP1RJMi+krxU1A3Yux4bpwZNLvVBKy0wLgM=
    2trusted comment: review ACK 2656a5658c14b43c32959db7235e9db55a17d4c8 🏼
    38rJpj3CDdDpna05UotXDyfLiqqhCsEUjIzBw/yCLmpTSLtB4f5whzkBtAgcYsMdq7aROp1S/UHZ45R1B4v6ODQ==
    
  19. DrahtBot requested review from hebasto on Jan 17, 2025
  20. DrahtBot requested review from davidgumberg on Jan 17, 2025
  21. Sjors commented at 1:35 pm on January 17, 2025: member

    This caused an incompatibility with blocksdirs from previous versions of Core. Setting to draft whlie I play around with a fix.

    Once you figure that out, you can use a previous release to demonstrate that this works. See e.g. mempool_compatibility.py.

  22. theuni marked this as ready for review on Jan 17, 2025
  23. theuni commented at 8:04 pm on January 17, 2025: member

    This caused an incompatibility with blocksdirs from previous versions of Core. Setting to draft whlie I play around with a fix.

    Once you figure that out, you can use a previous release to demonstrate that this works. See e.g. mempool_compatibility.py.

    The compatibility problem was actually caught by the feature_unsupported_utxo_db previous release check. So passing here indicates that we’re good with old blockstores (and thankfully that we have a working check for that :)

  24. TheCharlatan commented at 1:46 pm on January 18, 2025: contributor

    It’s not likely to happen currently, but may be more relevant in the future with applications using the kernel. Note that the kernel does not currently do any dir locking, but it should.

    I think if we want directory locking in the kernel library, we should do that here before we introduce and ossify new assumptions on when exactly the lock is taken. As an alternative, how about taking the lock in the BlockManager constructor, like done here https://github.com/TheCharlatan/bitcoin/tree/lock_blocksdir_raii.

  25. BrandonOdiwuor commented at 6:30 pm on January 18, 2025: contributor
    Concept ACK
  26. tdb3 approved
  27. tdb3 commented at 2:40 am on January 20, 2025: contributor

    Code review and light test ACK 2656a5658c14b43c32959db7235e9db55a17d4c8

    Nice update. Increasing safety for blocks dir before concurrency issues arise makes sense.

    Sanity checked the migration from .lockless blocks dir on signet. New .lock was created without issue.

  28. DrahtBot requested review from BrandonOdiwuor on Jan 20, 2025
  29. maflcko commented at 8:50 am on January 20, 2025: member

    No change since my last review. I just mis-read the test commit.

    re-ACK 2656a5658c14b43c32959db7235e9db55a17d4c8 🐓

    Signature:

    0untrusted comment: signature from minisign secret key on empty file; verify via: minisign -Vm "${path_to_any_empty_file}" -P RWTRmVTMeKV5noAMqVlsMugDDCyyTSbA3Re5AkUrhvLVln0tSaFWglOw -x "${path_to_this_whole_four_line_signature_blob}"
    1RUTRmVTMeKV5npGrKx1nqXCw5zeVHdtdYURB/KlyA/LMFgpNCs+SkW9a8N95d+U4AP1RJMi+krxU1A3Yux4bpwZNLvVBKy0wLgM=
    2trusted comment: re-ACK 2656a5658c14b43c32959db7235e9db55a17d4c8 🐓
    3z/AuyZTvEwZ4aF6WePeTTDgAPquZT5sd1uLNwLP1zxYViAM+8hrg/lW1cznwZ8JdkBvGYwzk6AqgFGWTzKDfBA==
    

github-metadata-mirror

This is a metadata mirror of the GitHub repository bitcoin/bitcoin. This site is not affiliated with GitHub. Content is generated from a GitHub metadata backup.
generated: 2025-01-21 03:12 UTC

This site is hosted by @0xB10C
More mirrored repositories can be found on mirror.b10c.me