From: Kent Overstreet Date: Thu, 28 Nov 2019 20:08:27 +0000 (-0500) Subject: Merge commit '780de81b36' X-Git-Url: https://git.sesse.net/?a=commitdiff_plain;h=ffced87f08a9ff929f78fd941536d4f88507588a;hp=8c20176f2ce40fc8b0151e5a7d17561dd0eda0b5;p=bcachefs-tools-debian Merge commit '780de81b36' --- diff --git a/INSTALL b/INSTALL index 46833a3..0c37c4a 100644 --- a/INSTALL +++ b/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 diff --git a/Makefile b/Makefile index eb2798f..adea761 100644 --- a/Makefile +++ b/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)) diff --git a/bcachefs.c b/bcachefs.c index 8840d51..03ebfd2 100644 --- a/bcachefs.c +++ b/bcachefs.c @@ -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(); diff --git a/cmd_fusemount.c b/cmd_fusemount.c index 96a2339..4e4c24c 100644 --- a/cmd_fusemount.c +++ b/cmd_fusemount.c @@ -1,3 +1,5 @@ +#ifdef BCACHEFS_FUSE + #include #include #include @@ -1262,3 +1264,5 @@ out: return ret ? 1 : 0; } + +#endif /* BCACHEFS_FUSE */ diff --git a/tests/test_fixture.py b/tests/test_fixture.py index 74a896b..d8d3819 100644 --- a/tests/test_fixture.py +++ b/tests/test_fixture.py @@ -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) diff --git a/tests/test_fuse.py b/tests/test_fuse.py index 877fd64..c7608f4 100644 --- a/tests/test_fuse.py +++ b/tests/test_fuse.py @@ -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() diff --git a/tests/util.py b/tests/util.py index 18d6002..fd8efd4 100644 --- a/tests/util.py +++ b/tests/util.py @@ -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