diff --git a/test/benchmarks/fs/BUILD b/test/benchmarks/fs/BUILD index f606daf0e..2e6970671 100644 --- a/test/benchmarks/fs/BUILD +++ b/test/benchmarks/fs/BUILD @@ -22,6 +22,7 @@ benchmark_test( benchmark_test( name = "fio_test", srcs = ["fio_test.go"], + data = ["//test/runner/fuse"], visibility = ["//:sandbox"], deps = [ "//pkg/cleanup", diff --git a/test/benchmarks/fs/fio_test.go b/test/benchmarks/fs/fio_test.go index 9b50633c2..5537182e3 100644 --- a/test/benchmarks/fs/fio_test.go +++ b/test/benchmarks/fs/fio_test.go @@ -114,12 +114,13 @@ func BenchmarkFio(b *testing.B) { b.Fatalf("failed to make mount: %v", err) } + runOpts := dockerutil.RunOpts{ + Image: "benchmarks/fio", + Mounts: mnts, + } // Start the container with the mount. if err := container.Spawn( - ctx, dockerutil.RunOpts{ - Image: "benchmarks/fio", - Mounts: mnts, - }, + ctx, runOpts, // Sleep on the order of b.N. "sleep", fmt.Sprintf("%d", 1000*b.N), ); err != nil { @@ -131,6 +132,16 @@ func BenchmarkFio(b *testing.B) { b.Fatalf("failed to copy directory: %v (%s)", err, out) } + if fsType == harness.FuseFS { + container.CopyFiles(&runOpts, "/fusebin", "test/runner/fuse/fuse") + _, err := container.ExecProcess(ctx, dockerutil.ExecOpts{ + Privileged: true, + }, "/fusebin/fuse", "--dir="+outdir, "--debug=false") + if err != nil { + b.Fatalf("starting fuse server failed with: %v", err) + } + } + // Directory and filename inside container where fio will read/write. outfile := filepath.Join(outdir, "test.txt") diff --git a/test/benchmarks/fs/fsbench/BUILD b/test/benchmarks/fs/fsbench/BUILD index 247454057..fa3e93af8 100644 --- a/test/benchmarks/fs/fsbench/BUILD +++ b/test/benchmarks/fs/fsbench/BUILD @@ -12,6 +12,7 @@ go_library( name = "fsbench", testonly = 1, srcs = ["fsbench.go"], + data = ["//test/runner/fuse"], deps = [ "//pkg/cleanup", "//pkg/test/dockerutil", diff --git a/test/benchmarks/fs/fsbench/fsbench.go b/test/benchmarks/fs/fsbench/fsbench.go index 55f7ee88a..3eac6977f 100644 --- a/test/benchmarks/fs/fsbench/fsbench.go +++ b/test/benchmarks/fs/fsbench/fsbench.go @@ -42,7 +42,7 @@ type FSBenchmark struct { WantOutput string // CleanCmd, if set, is run to clean up between benchmarks. CleanCmd []string - // Variants is a list of benchmarka variants to run. + // Variants is a list of benchmark variants to run. // If unset, the typical set is used. Variants []Variant // Callback is an optional function that is called after each execution of @@ -63,8 +63,8 @@ type Variant struct { // TypicalVariants returns the typical full set of benchmark variants. func TypicalVariants() []Variant { - variants := make([]Variant, 0, 6) - for _, filesys := range []harness.FileSystemType{harness.BindFS, harness.TmpFS, harness.RootFS} { + variants := make([]Variant, 0, 8) + for _, filesys := range []harness.FileSystemType{harness.FuseFS} { variants = append(variants, Variant{ clearCache: true, fsType: filesys, @@ -125,7 +125,24 @@ func RunWithDifferentFilesystems(ctx context.Context, b *testing.B, machine harn b.Fatalf("run failed with: %v", err) } - cpCmd := fmt.Sprintf("mkdir -p %s && cp -r %s %s/.", prefix, bm.WorkDir, prefix) + // Ignore safetext/shsprintf linter suggestion. + mkdirCmd := fmt.Sprintf("mkdir -p %s", prefix) + out, err := container.Exec(ctx, dockerutil.ExecOpts{}, "/bin/sh", "-c", mkdirCmd) + if err != nil { + b.Fatalf("failed to make directory: %v (%s)", err, out) + } + + if variant.fsType == harness.FuseFS { + container.CopyFiles(&runOpts, "/fusebin", "test/runner/fuse/fuse") + _, err := container.ExecProcess(ctx, dockerutil.ExecOpts{ + Privileged: true, + }, "/fusebin/fuse", "--dir="+prefix, "--debug=false") + if err != nil { + b.Fatalf("starting fuse server failed with: %v", err) + } + } + + cpCmd := fmt.Sprintf("cp -r %s %s/.", bm.WorkDir, prefix) if out, err := container.Exec(ctx, dockerutil.ExecOpts{}, "/bin/sh", "-c", cpCmd); err != nil { b.Fatalf("failed to copy directory: %v (%s)", err, out) diff --git a/test/benchmarks/harness/util.go b/test/benchmarks/harness/util.go index ae1712170..a511ec06a 100644 --- a/test/benchmarks/harness/util.go +++ b/test/benchmarks/harness/util.go @@ -69,13 +69,15 @@ const ( TmpFS FileSystemType = "tmpfs" // RootFS indicates no mount should be created and the root mount should be used. RootFS FileSystemType = "rootfs" + // FuseFS indicates a passthrough fuse server should be created. + FuseFS FileSystemType = "fusefs" ) // MakeMount makes a mount and cleanup based on the requested type. Bind // and volume mounts are backed by a temp directory made with mktemp. // tmpfs mounts require no such backing and are just made. -// rootfs mounts do not make a mount, but instead return a target direectory at root. -// It is up to the caller to call Clean on the passed *cleanup.Cleanup +// rootfs mounts do not make a mount, but instead return a target directory at +// root. It is up to the caller to call Clean on the passed *cleanup.Cleanup. func MakeMount(machine Machine, fsType FileSystemType, cu *cleanup.Cleanup) ([]mount.Mount, string, error) { mounts := make([]mount.Mount, 0, 1) target := "/data" @@ -107,6 +109,18 @@ func MakeMount(machine Machine, fsType FileSystemType, cu *cleanup.Cleanup) ([]m Type: mount.TypeTmpfs, }) return mounts, target, nil + case FuseFS: + mounts = append(mounts, []mount.Mount{ + { + Target: target, + Type: mount.TypeTmpfs, + }, + { + Target: "/fuse", + Type: mount.TypeTmpfs, + }, + }...) + return mounts, target, nil default: return mounts, "", fmt.Errorf("illegal mount type not supported: %v", fsType) } diff --git a/test/runner/fuse/BUILD b/test/runner/fuse/BUILD index c8b9e24b9..584752841 100644 --- a/test/runner/fuse/BUILD +++ b/test/runner/fuse/BUILD @@ -8,7 +8,10 @@ package( go_binary( name = "fuse", srcs = ["fuse.go"], - visibility = ["//test/runner:__subpackages__"], + visibility = [ + "//test/benchmarks:__subpackages__", + "//test/runner:__subpackages__", + ], deps = [ "//pkg/log", "//runsc/specutils", diff --git a/test/runner/fuse/fuse.go b/test/runner/fuse/fuse.go index 64bc0cba0..14efc5acf 100644 --- a/test/runner/fuse/fuse.go +++ b/test/runner/fuse/fuse.go @@ -59,7 +59,7 @@ func main() { } opts := &fuse.MountOptions{DirectMountStrict: true, Debug: *debug, AllowOther: true, Options: []string{"default_permissions"}} rawFS := fs.NewNodeFS(loopbackRoot, &fs.Options{NullPermissions: true, Logger: golog.Default()}) - server, err := fuse.NewServer(rawFS, "/tmp", opts) + server, err := fuse.NewServer(rawFS, *dir, opts) if err != nil { log.Warningf("could not create fuse server: %v", err) os.Exit(1)