mirror of
https://github.com/koverstreet/bcachefs-tools.git
synced 2025-12-09 00:00:17 +03:00
Merge commit '780de81b36'
This commit is contained in:
commit
ffced87f08
34
INSTALL
34
INSTALL
@ -1,3 +1,4 @@
|
||||
-- Getting started --
|
||||
|
||||
Dependencies:
|
||||
|
||||
@ -20,3 +21,36 @@ On debian, you can install these with
|
||||
uuid-dev zlib1g-dev valgrind
|
||||
|
||||
Then, just make && make install
|
||||
|
||||
|
||||
-- Experimental features --
|
||||
|
||||
Experimental fuse support is currently disabled by default. Fuse support is at
|
||||
an early stage and may corrupt your filesystem, so it should only be used for
|
||||
testing. To enable, you'll also need to add:
|
||||
|
||||
* libfuse3
|
||||
|
||||
On debian:
|
||||
apt install -y libfuse3-dev
|
||||
|
||||
Then, make using the BCACHEFS_FUSE environment variable:
|
||||
|
||||
BCACHEFS_FUSE=1 make &&
|
||||
|
||||
|
||||
-- Tests --
|
||||
|
||||
Some tests are available to validate the "bcachefs" binary. The tests depend
|
||||
on python3 pytest.
|
||||
|
||||
On debian:
|
||||
apt install -u python3-pytest
|
||||
|
||||
Then, you can run the tests via:
|
||||
|
||||
make check
|
||||
|
||||
Optionally, you may wish to run tests in parallel using python3-pytest-xdist:
|
||||
|
||||
cd tests; pytest-3 -n4
|
||||
|
||||
6
Makefile
6
Makefile
@ -38,7 +38,11 @@ ifdef D
|
||||
CFLAGS+=-DCONFIG_BCACHEFS_DEBUG=y
|
||||
endif
|
||||
|
||||
PKGCONFIG_LIBS="blkid uuid liburcu libsodium zlib liblz4 libzstd fuse3"
|
||||
PKGCONFIG_LIBS="blkid uuid liburcu libsodium zlib liblz4 libzstd"
|
||||
ifdef BCACHEFS_FUSE
|
||||
PKGCONFIG_LIBS+="fuse3"
|
||||
CFLAGS+=-DBCACHEFS_FUSE
|
||||
endif
|
||||
|
||||
PKGCONFIG_CFLAGS:=$(shell $(PKG_CONFIG) --cflags $(PKGCONFIG_LIBS))
|
||||
ifeq (,$(PKGCONFIG_CFLAGS))
|
||||
|
||||
@ -203,8 +203,10 @@ int main(int argc, char *argv[])
|
||||
if (!strcmp(cmd, "setattr"))
|
||||
return cmd_setattr(argc, argv);
|
||||
|
||||
#ifdef BCACHEFS_FUSE
|
||||
if (!strcmp(cmd, "fusemount"))
|
||||
return cmd_fusemount(argc, argv);
|
||||
#endif
|
||||
|
||||
if (!strcmp(cmd, "--help")) {
|
||||
usage();
|
||||
|
||||
@ -1,3 +1,5 @@
|
||||
#ifdef BCACHEFS_FUSE
|
||||
|
||||
#include <errno.h>
|
||||
#include <float.h>
|
||||
#include <getopt.h>
|
||||
@ -1262,3 +1264,5 @@ out:
|
||||
|
||||
return ret ? 1 : 0;
|
||||
}
|
||||
|
||||
#endif /* BCACHEFS_FUSE */
|
||||
|
||||
@ -29,26 +29,32 @@ def test_segfault():
|
||||
ret = util.run(helper, 'segfault')
|
||||
assert ret.returncode == -signal.SIGSEGV
|
||||
|
||||
@pytest.mark.skipif(not util.ENABLE_VALGRIND, reason="no valgrind")
|
||||
def test_check():
|
||||
with pytest.raises(subprocess.CalledProcessError):
|
||||
ret = util.run(helper, 'abort', check=True)
|
||||
|
||||
@pytest.mark.skipif(not util.ENABLE_VALGRIND, reason="no valgrind")
|
||||
def test_leak():
|
||||
with pytest.raises(util.ValgrindFailedError):
|
||||
ret = util.run(helper, 'leak', valgrind=True)
|
||||
|
||||
@pytest.mark.skipif(not util.ENABLE_VALGRIND, reason="no valgrind")
|
||||
def test_undefined():
|
||||
with pytest.raises(util.ValgrindFailedError):
|
||||
ret = util.run(helper, 'undefined', valgrind=True)
|
||||
|
||||
@pytest.mark.skipif(not util.ENABLE_VALGRIND, reason="no valgrind")
|
||||
def test_undefined_branch():
|
||||
with pytest.raises(util.ValgrindFailedError):
|
||||
ret = util.run(helper, 'undefined_branch', valgrind=True)
|
||||
|
||||
@pytest.mark.skipif(not util.ENABLE_VALGRIND, reason="no valgrind")
|
||||
def test_read_after_free():
|
||||
with pytest.raises(util.ValgrindFailedError):
|
||||
ret = util.run(helper, 'read_after_free', valgrind=True)
|
||||
|
||||
@pytest.mark.skipif(not util.ENABLE_VALGRIND, reason="no valgrind")
|
||||
def test_write_after_free():
|
||||
with pytest.raises(util.ValgrindFailedError):
|
||||
ret = util.run(helper, 'write_after_free', valgrind=True)
|
||||
|
||||
@ -2,14 +2,25 @@
|
||||
#
|
||||
# Tests of the fuse mount functionality.
|
||||
|
||||
import pytest
|
||||
import os
|
||||
import util
|
||||
|
||||
pytestmark = pytest.mark.skipif(
|
||||
not util.have_fuse(), reason="bcachefs not built with fuse support.")
|
||||
|
||||
def test_mount(bfuse):
|
||||
bfuse.mount()
|
||||
bfuse.unmount()
|
||||
bfuse.verify()
|
||||
|
||||
def test_remount(bfuse):
|
||||
bfuse.mount()
|
||||
bfuse.unmount()
|
||||
bfuse.mount()
|
||||
bfuse.unmount()
|
||||
bfuse.verify()
|
||||
|
||||
def test_lostfound(bfuse):
|
||||
bfuse.mount()
|
||||
|
||||
|
||||
@ -4,6 +4,7 @@ import os
|
||||
import pytest
|
||||
import re
|
||||
import subprocess
|
||||
import sys
|
||||
import tempfile
|
||||
import threading
|
||||
import time
|
||||
@ -15,6 +16,8 @@ BCH_PATH = DIR / 'bcachefs'
|
||||
|
||||
VPAT = re.compile(r'ERROR SUMMARY: (\d+) errors from (\d+) contexts')
|
||||
|
||||
ENABLE_VALGRIND = os.getenv('BCACHEFS_TEST_USE_VALGRIND', 'yes') == 'yes'
|
||||
|
||||
class ValgrindFailedError(Exception):
|
||||
def __init__(self, log):
|
||||
self.log = log
|
||||
@ -36,6 +39,7 @@ def run(cmd, *args, valgrind=False, check=False):
|
||||
ValgrindFailedError if there's a problem.
|
||||
"""
|
||||
cmds = [cmd] + list(args)
|
||||
valgrind = valgrind and ENABLE_VALGRIND
|
||||
|
||||
if valgrind:
|
||||
vout = tempfile.NamedTemporaryFile()
|
||||
@ -123,7 +127,7 @@ class FuseError(Exception):
|
||||
def __init__(self, msg):
|
||||
self.msg = msg
|
||||
|
||||
class BFuse(threading.Thread):
|
||||
class BFuse:
|
||||
'''bcachefs fuse runner.
|
||||
|
||||
This class runs bcachefs in fusemount mode, and waits until the mount has
|
||||
@ -133,7 +137,7 @@ class BFuse(threading.Thread):
|
||||
'''
|
||||
|
||||
def __init__(self, dev, mnt):
|
||||
threading.Thread.__init__(self)
|
||||
self.thread = None
|
||||
self.dev = dev
|
||||
self.mnt = mnt
|
||||
self.ready = threading.Event()
|
||||
@ -146,12 +150,17 @@ class BFuse(threading.Thread):
|
||||
def run(self):
|
||||
"""Background thread which runs "bcachefs fusemount" under valgrind"""
|
||||
|
||||
vout = tempfile.NamedTemporaryFile()
|
||||
cmd = [ 'valgrind',
|
||||
'--leak-check=full',
|
||||
'--log-file={}'.format(vout.name),
|
||||
BCH_PATH,
|
||||
'fusemount', '-f', self.dev, self.mnt]
|
||||
vout = None
|
||||
cmd = []
|
||||
|
||||
if ENABLE_VALGRIND:
|
||||
vout = tempfile.NamedTemporaryFile()
|
||||
cmd += [ 'valgrind',
|
||||
'--leak-check=full',
|
||||
'--log-file={}'.format(vout.name) ]
|
||||
|
||||
cmd += [ BCH_PATH,
|
||||
'fusemount', '-f', self.dev, self.mnt]
|
||||
|
||||
print("Running {}".format(cmd))
|
||||
|
||||
@ -188,7 +197,11 @@ class BFuse(threading.Thread):
|
||||
|
||||
def mount(self):
|
||||
print("Starting fuse thread.")
|
||||
self.start()
|
||||
|
||||
assert not self.thread
|
||||
self.thread = threading.Thread(target=self.run)
|
||||
self.thread.start()
|
||||
|
||||
self.ready.wait()
|
||||
print("Fuse is mounted.")
|
||||
|
||||
@ -197,14 +210,22 @@ class BFuse(threading.Thread):
|
||||
run("fusermount3", "-zu", self.mnt)
|
||||
print("Waiting for thread to exit.")
|
||||
|
||||
self.join(timeout)
|
||||
if self.isAlive():
|
||||
self.thread.join(timeout)
|
||||
if self.thread.is_alive():
|
||||
self.proc.kill()
|
||||
self.join()
|
||||
self.thread.join()
|
||||
|
||||
check_valgrind(self.vout)
|
||||
self.thread = None
|
||||
self.ready.clear()
|
||||
|
||||
if self.vout:
|
||||
check_valgrind(self.vout)
|
||||
|
||||
def verify(self):
|
||||
assert self.returncode == 0
|
||||
assert len(self.stdout) > 0
|
||||
assert len(self.stderr) == 0
|
||||
|
||||
def have_fuse():
|
||||
res = run(BCH_PATH, 'fusemount', valgrind=False)
|
||||
return "Please supply a mountpoint." in res.stdout
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user