summaryrefslogtreecommitdiffhomepage
path: root/pkg
diff options
context:
space:
mode:
authorBoyuan He & Ridwan Sharif <heboyuan@google.com>2020-08-26 15:26:46 -0400
committerAndrei Vagin <avagin@gmail.com>2020-09-11 13:35:25 -0700
commit9cc683af1e5c003ccc4f5a72e6b5b207e8426e1a (patch)
tree60a6a891af2dbe40cef0d77a5fe2fc520470d9e7 /pkg
parent3bd85840c8f0364083c88d65c2bc1f968069b04e (diff)
fuse: add benchmarking support for FUSE
This change adds the following: - Add support for containerizing syscall tests for FUSE - Mount tmpfs in the container so we can run benchmarks against it - Run the server in a background process - benchmarks for fuse syscall Co-authored-by: Ridwan Sharif <ridwanmsharif@google.com>
Diffstat (limited to 'pkg')
-rw-r--r--pkg/sentry/fs/g3doc/fuse.md47
-rw-r--r--pkg/test/dockerutil/container.go10
-rw-r--r--pkg/test/dockerutil/dockerutil.go20
3 files changed, 77 insertions, 0 deletions
diff --git a/pkg/sentry/fs/g3doc/fuse.md b/pkg/sentry/fs/g3doc/fuse.md
index 2ca84dd74..496e339ce 100644
--- a/pkg/sentry/fs/g3doc/fuse.md
+++ b/pkg/sentry/fs/g3doc/fuse.md
@@ -254,6 +254,53 @@ I/O syscalls like `read(2)`, `write(2)` and `mmap(2)`.
- `FUSE_BMAP`: Old address space API for block defrag. Probably not needed.
- `FUSE_NOTIFY_REPLY`: [TODO: what does this do?]
+## Benchmark FUSE
+
+FUSE benchmark makes FUSE syscall inside docker container to make sure required
+environment conditions are met - such as having the right libraries to start a
+FUSE server.
+
+### Setup
+
+To run benchmark:
+
+1. Make sure you have `Docker` installed.
+2. Download all docker images `make load-all-images`.
+3. Config `runsc` docker runtime to have VFS2 and FUSE supported.
+(e.g. `make configure RUNTIME=runsc ARGS="--vfs2 --fuse ..." ...`)
+
+You should now have a runtime with the following options configured in
+`/etc/docker/daemon.json`
+```
+"runsc": {
+ "path": "path/to/your/runsc",
+ "runtimeArgs": [
+ "--vfs2",
+ "--fuse"
+ ...
+ ]
+ }
+```
+
+### Running benchmarks
+With above setup, benchmark can be run with following command
+```
+bazel test --test_output=all --cache_test_results=no --test_arg=-test.bench= //path/to:target
+```
+For example: if you want to run stat test
+```
+bazel test --test_output=all --cache_test_results=no --test_arg=-test.bench= //test/fuse:open_benchmark_runsc_ptrace_vfs2_fuse_container
+```
+
+Note:
+- test target need to have `vfs2_fuse_container` to run in container with `vfs2` and `fuse` enabled
+- `test_output` set to `all` to view the result in terminal
+- `--cache_test_results` set to `no` to avoid cached benchmark
+
+### Use your fuse server
+
+To use your own FUSE server, change the `images/basic/fuse/Dockerfile` to compile your FUSE server into the container and name it `server-bin`.
+
# References
- [fuse(4) Linux manual page](https://www.man7.org/linux/man-pages/man4/fuse.4.html)
diff --git a/pkg/test/dockerutil/container.go b/pkg/test/dockerutil/container.go
index 64d17f661..727be26b2 100644
--- a/pkg/test/dockerutil/container.go
+++ b/pkg/test/dockerutil/container.go
@@ -136,6 +136,11 @@ func MakeNativeContainer(ctx context.Context, logger testutil.Logger) *Container
}
}
+// Runtime returns the runtime of the container.
+func (c *Container) Runtime() string {
+ return c.runtime
+}
+
// AddProfile adds a profile to this container.
func (c *Container) AddProfile(p Profile) {
c.profiles = append(c.profiles, p)
@@ -541,3 +546,8 @@ func (c *Container) CleanUp(ctx context.Context) {
// Forget all mounts.
c.mounts = nil
}
+
+// CopyErr returns the error that happened during copy.
+func (c *Container) CopyErr() error {
+ return c.copyErr
+}
diff --git a/pkg/test/dockerutil/dockerutil.go b/pkg/test/dockerutil/dockerutil.go
index 7027df1a5..a2d7e8c85 100644
--- a/pkg/test/dockerutil/dockerutil.go
+++ b/pkg/test/dockerutil/dockerutil.go
@@ -121,6 +121,26 @@ func UsingVFS2() (bool, error) {
return false, nil
}
+// UsingFUSE returns true if the 'runtime' has the fuse flag set.
+func UsingFUSE() (bool, error) {
+ rMap, err := runtimeMap()
+ if err != nil {
+ return false, err
+ }
+
+ list, ok := rMap["runtimeArgs"].([]interface{})
+ if !ok {
+ return false, fmt.Errorf("unexpected format: %v", rMap)
+ }
+
+ for _, element := range list {
+ if element == "--fuse" {
+ return true, nil
+ }
+ }
+ return false, nil
+}
+
func runtimeMap() (map[string]interface{}, error) {
// Read the configuration data; the file must exist.
configBytes, err := ioutil.ReadFile(*config)