diff options
author | Boyuan He & Ridwan Sharif <heboyuan@google.com> | 2020-08-26 15:26:46 -0400 |
---|---|---|
committer | Andrei Vagin <avagin@gmail.com> | 2020-09-11 13:35:25 -0700 |
commit | 9cc683af1e5c003ccc4f5a72e6b5b207e8426e1a (patch) | |
tree | 60a6a891af2dbe40cef0d77a5fe2fc520470d9e7 /pkg | |
parent | 3bd85840c8f0364083c88d65c2bc1f968069b04e (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.md | 47 | ||||
-rw-r--r-- | pkg/test/dockerutil/container.go | 10 | ||||
-rw-r--r-- | pkg/test/dockerutil/dockerutil.go | 20 |
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) |