]> git.sesse.net Git - bcachefs-tools-debian/commitdiff
Merge commit '780de81b36'
authorKent Overstreet <kent.overstreet@gmail.com>
Thu, 28 Nov 2019 20:08:27 +0000 (15:08 -0500)
committerKent Overstreet <kent.overstreet@gmail.com>
Thu, 28 Nov 2019 20:08:27 +0000 (15:08 -0500)
INSTALL
Makefile
bcachefs.c
cmd_fusemount.c
tests/test_fixture.py
tests/test_fuse.py
tests/util.py

diff --git a/INSTALL b/INSTALL
index 46833a392eb15637b4a2f5475f964bf4420f4529..0c37c4a07e42bd00549cfaa0d92b263449be6ceb 100644 (file)
--- 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
index eb2798ff5a5d6b2382cb7424574cb52263930e4d..adea7611d8092a0f81b1431bf61ae4593a72b7c7 100644 (file)
--- 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))
index 8840d5161d6308de42552c9914e8f165f87fc78c..03ebfd2017e6454b171a01e5a402e6e769af27d2 100644 (file)
@@ -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();
index 96a2339d2dcf801301e9a724644d8f448ba293d1..4e4c24cce888b28679841097e49a4961c2e9b70a 100644 (file)
@@ -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 */
index 74a896bace4122597c8007f6662dceba317420f8..d8d3819e814427473b4f171a75c09f79d1650312 100644 (file)
@@ -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)
index 877fd64c7c8f50343836221dba383a738c55fa3e..c7608f4c85dbb6e098723cc99a078cae6c9af595 100644 (file)
@@ -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()
 
index 18d60020c3056f81dd06e3868a7211a73a1e173a..fd8efd4750082e2ffb539068ce53cb889f1bf377 100644 (file)
@@ -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