Skip to content

Commit

Permalink
Merge bitcoin#28660: test: enable reindex readonly test on *BSD
Browse files Browse the repository at this point in the history
5a0688a test: enable reindex readonly test on *BSD and macOS as root (Matthew Zipkin)

Pull request description:

  see bitcoin#27850 (comment)

  OpenBSD and FreeBSD don't have `chattr` but they do have `chflags`, use that method to make the block file immutable for the reindex_readonly test.

  Written and tested on a VPS running FreeBSD:
  ```
  FreeBSD freebsd-13-1 13.2-RELEASE-p4 FreeBSD 13.2-RELEASE-p4 GENERIC amd64
  ```

ACKs for top commit:
  maflcko:
    re-cr-lgtm-ACK 5a0688a
  jonatack:
    ACK 5a0688a tested on macOS only
  theStack:
    ACK 5a0688a

Tree-SHA512: 8c88d282d09c00355d22c4c504b779f60e420327a5e07bcf80fa77b97fefcb04952af9ceaf439d9033a0a2448cb26a02663fe6bddcd4a74792857cfbaf1c5162
  • Loading branch information
fanquake committed Oct 24, 2023
2 parents d724bb5 + 5a0688a commit ab61087
Showing 1 changed file with 31 additions and 12 deletions.
43 changes: 31 additions & 12 deletions test/functional/feature_reindex_readonly.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,6 @@
"""

import os
import platform
import stat
import subprocess
from test_framework.test_framework import BitcoinTestFramework
Expand All @@ -34,11 +33,13 @@ def reindex_readonly(self):
filename = self.nodes[0].chain_path / "blocks" / "blk00000.dat"
filename.chmod(stat.S_IREAD)

used_chattr = False
if platform.system() == "Linux":
undo_immutable = lambda: None
# Linux
try:
subprocess.run(['chattr'], stdout=subprocess.DEVNULL, stderr=subprocess.DEVNULL)
try:
subprocess.run(['chattr', '+i', filename], capture_output=True, check=True)
used_chattr = True
undo_immutable = lambda: subprocess.check_call(['chattr', '-i', filename])
self.log.info("Made file immutable with chattr")
except subprocess.CalledProcessError as e:
self.log.warning(str(e))
Expand All @@ -50,15 +51,33 @@ def reindex_readonly(self):
self.log.warning("Return early on Linux under root, because chattr failed.")
self.log.warning("This should only happen due to missing capabilities in a container.")
self.log.warning("Make sure to --cap-add LINUX_IMMUTABLE if you want to run this test.")
return

self.log.debug("Attempt to restart and reindex the node with the unwritable block file")
with self.nodes[0].assert_debug_log(expected_msgs=['FlushStateToDisk', 'failed to open file'], unexpected_msgs=[]):
self.nodes[0].assert_start_raises_init_error(extra_args=['-reindex', '-fastprune'],
expected_msg="Error: A fatal internal error occurred, see debug.log for details")
undo_immutable = False
except Exception:
# macOS, and *BSD
try:
subprocess.run(['chflags'], stdout=subprocess.DEVNULL, stderr=subprocess.DEVNULL)
try:
subprocess.run(['chflags', 'uchg', filename], capture_output=True, check=True)
undo_immutable = lambda: subprocess.check_call(['chflags', 'nouchg', filename])
self.log.info("Made file immutable with chflags")
except subprocess.CalledProcessError as e:
self.log.warning(str(e))
if e.stdout:
self.log.warning(f"stdout: {e.stdout}")
if e.stderr:
self.log.warning(f"stderr: {e.stderr}")
if os.getuid() == 0:
self.log.warning("Return early on BSD under root, because chflags failed.")
undo_immutable = False
except Exception:
pass

if used_chattr:
subprocess.check_call(['chattr', '-i', filename])
if undo_immutable:
self.log.info("Attempt to restart and reindex the node with the unwritable block file")
with self.nodes[0].assert_debug_log(expected_msgs=['FlushStateToDisk', 'failed to open file'], unexpected_msgs=[]):
self.nodes[0].assert_start_raises_init_error(extra_args=['-reindex', '-fastprune'],
expected_msg="Error: A fatal internal error occurred, see debug.log for details")
undo_immutable()

filename.chmod(0o777)

Expand Down

0 comments on commit ab61087

Please sign in to comment.