Skip to content

Commit

Permalink
EXPERIMENT vhost server for virtioFS
Browse files Browse the repository at this point in the history
  • Loading branch information
hanwen committed Nov 1, 2024
1 parent f7467d4 commit 021d63a
Show file tree
Hide file tree
Showing 4 changed files with 1,557 additions and 0 deletions.
51 changes: 51 additions & 0 deletions example/virtiofs/main.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
// Copyright 2024 the Go-FUSE Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.

package main

import (
"flag"
"log"
"net"

"github.com/hanwen/go-fuse/v2/fs"
"github.com/hanwen/go-fuse/v2/fuse"
"github.com/hanwen/go-fuse/v2/vhostuser"
)

func main() {
log.SetFlags(log.Lmicroseconds)
flag.Parse()

sockpath := flag.Arg(0)
orig := flag.Arg(1)
l, err := net.ListenUnix("unix", &net.UnixAddr{sockpath, "unix"})
if err != nil {
log.Fatal("Listen", err)
}

root, err := fs.NewLoopbackRoot(orig)
if err != nil {
log.Fatal(err)
}
opts := &fs.Options{}
opts.Debug = true
opts.Logger = log.Default()
opts.MountOptions.Logger = opts.Logger
rawFS := fs.NewNodeFS(root, opts)
ps := fuse.NewProtocolServer(rawFS, &opts.MountOptions)

for {
conn, err := l.AcceptUnix()
if err != nil {
break
}

dev := vhostuser.NewFSDevice(ps)
srv := vhostuser.NewServer(conn, dev)
if err := srv.Serve(); err != nil {
log.Printf("Serve: %v %T", err, err)
}
}
}
81 changes: 81 additions & 0 deletions vhostuser/fs_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,81 @@
package vhostuser

import (
"log"
"net"
"os"
"os/exec"
"testing"

"github.com/hanwen/go-fuse/v2/fs"
"github.com/hanwen/go-fuse/v2/fuse"
)

func listenVFS(sockpath string, rawFS fuse.RawFileSystem, opts *fuse.MountOptions) {
os.Remove(sockpath)
l, err := net.ListenUnix("unix", &net.UnixAddr{sockpath, "unix"})
if err != nil {
log.Fatal("Listen", err)
}
for {
conn, err := l.AcceptUnix()
if err != nil {
break
}

ps := fuse.NewProtocolServer(rawFS, opts)
dev := NewFSDevice(ps)
srv := NewServer(conn, dev)
if err := srv.Serve(); err != nil {
log.Printf("Serve: %v %T", err, err)
}
}
}

func TestBasic(t *testing.T) {
orig := t.TempDir()
if err := os.WriteFile(orig+"/file.txt", []byte("hello world\n"), 0666); err != nil {
t.Errorf("WriteFile: %v", err)
}
root, err := fs.NewLoopbackRoot(orig)
if err != nil {
t.Fatal(err)
}
opts := &fs.Options{}
opts.Debug = true
opts.Logger = log.Default()
opts.MountOptions.Logger = opts.Logger
rawFS := fs.NewNodeFS(root, opts)

bindir := os.Getenv("HOME") + "/.cache/go-fuse-virtiofs"
sockpath := "/tmp/vhostqemu"
go listenVFS(sockpath, rawFS, &opts.MountOptions)

cmd := exec.Command("qemu-system-x86_64",
"-M", "pc", "-m", "4G", "-cpu", "host", "-smp", "2",
"-enable-kvm",

// to create the communications socket
"-chardev", "socket,id=char0,path="+sockpath,

// instantiate the device
"-device", "vhost-user-fs-pci,queue-size=1024,chardev=char0,tag=myfs",

// force use of memory sharable with virtiofsd.
"-object", "memory-backend-file,id=mem,size=4G,mem-path=/dev/shm,share=on", "-numa", "node,memdev=mem",

"-kernel", bindir+"/bzImage",
"-initrd", bindir+"/initramfs.cpio.gz",
"-nographic",
"-append",
"console=ttyS0",
)
cmd.Stdout = os.Stdout
cmd.Stderr = os.Stderr
if err := cmd.Start(); err != nil {
t.Fatal(err)
}
if err := cmd.Wait(); err != nil {
t.Fatal(err)
}
}
Loading

0 comments on commit 021d63a

Please sign in to comment.