Commit 7b4f97c3 authored by Han-Wen Nienhuys's avatar Han-Wen Nienhuys

fuse: add Options.Logger

This allows for specializing the debug output.

Change-Id: Id6a24fd6207253af3f32ca0f7ed51db3db31ced4
parent 0b3e1fde
......@@ -122,6 +122,8 @@
// [2] https://sylabs.io/guides/3.7/user-guide/bind_paths_and_mounts.html#fuse-mounts
package fuse
import "log"
// Types for users to implement.
// The result of Read is an array of bytes, but for performance
......@@ -219,6 +221,9 @@ type MountOptions struct {
// If set, print debugging information.
Debug bool
// If set, sink for debug statements.
Logger *log.Logger
// If set, ask kernel to forward file locks to FUSE. If using,
// you must implement the GetLk/SetLk/SetLkw methods.
EnableLocks bool
......
......@@ -7,7 +7,6 @@ package fuse
import (
"bytes"
"fmt"
"log"
"os"
"os/exec"
"path"
......@@ -69,7 +68,7 @@ func mountDirect(mountPoint string, opts *MountOptions, ready chan<- error) (fd
}
if opts.Debug {
log.Printf("mountDirect: calling syscall.Mount(%q, %q, %q, %#x, %q)",
opts.Logger.Printf("mountDirect: calling syscall.Mount(%q, %q, %q, %#x, %q)",
source, mountPoint, "fuse."+opts.Name, flags, strings.Join(r, ","))
}
err = syscall.Mount(source, mountPoint, "fuse."+opts.Name, flags, strings.Join(r, ","))
......@@ -108,7 +107,7 @@ func callFusermount(mountPoint string, opts *MountOptions) (fd int, err error) {
cmd = append(cmd, "-o", strings.Join(s, ","))
}
if opts.Debug {
log.Printf("callFusermount: executing %q", cmd)
opts.Logger.Printf("callFusermount: executing %q", cmd)
}
proc, err := os.StartProcess(bin,
cmd,
......@@ -145,7 +144,7 @@ func mount(mountPoint string, opts *MountOptions, ready chan<- error) (fd int, e
if err == nil {
return fd, nil
} else if opts.Debug {
log.Printf("mount: failed to do direct mount: %s", err)
opts.Logger.Printf("mount: failed to do direct mount: %s", err)
}
if opts.DirectMountStrict {
return -1, err
......@@ -157,7 +156,7 @@ func mount(mountPoint string, opts *MountOptions, ready chan<- error) (fd int, e
fd = parseFuseFd(mountPoint)
if fd >= 0 {
if opts.Debug {
log.Printf("mount: magic mountpoint %q, using fd %d", mountPoint, fd)
opts.Logger.Printf("mount: magic mountpoint %q, using fd %d", mountPoint, fd)
}
} else {
// Usual case: mount via the `fusermount` suid helper
......@@ -194,7 +193,7 @@ func unmount(mountPoint string, opts *MountOptions) (err error) {
cmd := exec.Command(bin, "-u", mountPoint)
cmd.Stderr = &errBuf
if opts.Debug {
log.Printf("unmount: executing %q", cmd.Args)
opts.Logger.Printf("unmount: executing %q", cmd.Args)
}
err = cmd.Run()
if errBuf.Len() > 0 {
......
......@@ -229,7 +229,7 @@ func doNotifyReply(server *Server, req *request) {
server.retrieveMu.Unlock()
badf := func(format string, argv ...interface{}) {
log.Printf("notify reply: "+format, argv...)
server.opts.Logger.Printf("notify reply: "+format, argv...)
}
if reading == nil {
......@@ -328,7 +328,7 @@ func doBatchForget(server *Server, req *request) {
wantBytes := uintptr(in.Count) * unsafe.Sizeof(_ForgetOne{})
if uintptr(len(req.arg)) < wantBytes {
// We have no return value to complain, so log an error.
log.Printf("Too few bytes for batch forget. Got %d bytes, want %d (%d entries)",
server.opts.Logger.Printf("Too few bytes for batch forget. Got %d bytes, want %d (%d entries)",
len(req.arg), wantBytes, in.Count)
}
......@@ -341,7 +341,7 @@ func doBatchForget(server *Server, req *request) {
forgets := *(*[]_ForgetOne)(unsafe.Pointer(h))
for i, f := range forgets {
if server.opts.Debug {
log.Printf("doBatchForget: rx %d %d/%d: FORGET n%d {Nlookup=%d}",
server.opts.Logger.Printf("doBatchForget: rx %d %d/%d: FORGET n%d {Nlookup=%d}",
req.inHeader.Unique, i+1, len(forgets), f.NodeId, f.Nlookup)
}
if f.NodeId == pollHackInode {
......
......@@ -165,7 +165,9 @@ func NewServer(fs RawFileSystem, mountPoint string, opts *MountOptions) (*Server
}
}
o := *opts
if o.Logger == nil {
o.Logger = log.Default()
}
if o.MaxWrite < 0 {
o.MaxWrite = 0
}
......@@ -483,11 +485,11 @@ exit:
case ENODEV:
// unmount
if ms.opts.Debug {
log.Printf("received ENODEV (unmount request), thread exiting")
ms.opts.Logger.Printf("received ENODEV (unmount request), thread exiting")
}
break exit
default: // some other error?
log.Printf("Failed to read from fuse conn: %v", errNo)
ms.opts.Logger.Printf("Failed to read from fuse conn: %v", errNo)
break exit
}
......@@ -511,14 +513,14 @@ func (ms *Server) handleRequest(req *request) Status {
}
if req.status.Ok() && ms.opts.Debug {
log.Println(req.InputDebug())
ms.opts.Logger.Println(req.InputDebug())
}
if req.inHeader.NodeId == pollHackInode ||
req.inHeader.NodeId == FUSE_ROOT_ID && len(req.filenames) > 0 && req.filenames[0] == pollHackName {
doPollHackLookup(ms, req)
} else if req.status.Ok() && req.handler.Func == nil {
log.Printf("Unimplemented opcode %v", operationName(req.inHeader.Opcode))
ms.opts.Logger.Printf("Unimplemented opcode %v", operationName(req.inHeader.Opcode))
req.status = ENOSYS
} else if req.status.Ok() {
req.handler.Func(ms, req)
......@@ -531,7 +533,7 @@ func (ms *Server) handleRequest(req *request) Status {
// kernel. This is a normal if the referred request already has
// completed.
if ms.opts.Debug || !(req.inHeader.Opcode == _OP_INTERRUPT && errNo == ENOENT) {
log.Printf("writer: Write/Writev failed, err: %v. opcode: %v",
ms.opts.Logger.Printf("writer: Write/Writev failed, err: %v. opcode: %v",
errNo, operationName(req.inHeader.Opcode))
}
......@@ -577,7 +579,7 @@ func (ms *Server) write(req *request) Status {
header := req.serializeHeader(req.flatDataSize())
if ms.opts.Debug {
log.Println(req.OutputDebug())
ms.opts.Logger.Println(req.OutputDebug())
}
if header == nil {
......@@ -614,7 +616,7 @@ func (ms *Server) InodeNotify(node uint64, off int64, length int64) Status {
ms.writeMu.Unlock()
if ms.opts.Debug {
log.Println("Response: INODE_NOTIFY", result)
ms.opts.Logger.Println("Response: INODE_NOTIFY", result)
}
return result
}
......@@ -673,7 +675,7 @@ func (ms *Server) inodeNotifyStoreCache32(node uint64, offset int64, data []byte
ms.writeMu.Unlock()
if ms.opts.Debug {
log.Printf("Response: INODE_NOTIFY_STORE_CACHE: %v", result)
ms.opts.Logger.Printf("Response: INODE_NOTIFY_STORE_CACHE: %v", result)
}
return result
}
......@@ -765,7 +767,7 @@ func (ms *Server) inodeRetrieveCache1(node uint64, offset int64, dest []byte) (n
ms.writeMu.Unlock()
if ms.opts.Debug {
log.Printf("Response: NOTIFY_RETRIEVE_CACHE: %v", result)
ms.opts.Logger.Printf("Response: NOTIFY_RETRIEVE_CACHE: %v", result)
}
if result != OK {
ms.retrieveMu.Lock()
......@@ -779,7 +781,7 @@ func (ms *Server) inodeRetrieveCache1(node uint64, offset int64, dest []byte) (n
// unexpected NotifyReply with our notifyUnique, then
// retrieveNext wraps, makes full cycle, and another
// retrieve request is made with the same notifyUnique.
log.Printf("W: INODE_RETRIEVE_CACHE: request with notifyUnique=%d mutated", q.NotifyUnique)
ms.opts.Logger.Printf("W: INODE_RETRIEVE_CACHE: request with notifyUnique=%d mutated", q.NotifyUnique)
}
ms.retrieveMu.Unlock()
return 0, result
......@@ -840,7 +842,7 @@ func (ms *Server) DeleteNotify(parent uint64, child uint64, name string) Status
ms.writeMu.Unlock()
if ms.opts.Debug {
log.Printf("Response: DELETE_NOTIFY: %v", result)
ms.opts.Logger.Printf("Response: DELETE_NOTIFY: %v", result)
}
return result
}
......@@ -876,7 +878,7 @@ func (ms *Server) EntryNotify(parent uint64, name string) Status {
ms.writeMu.Unlock()
if ms.opts.Debug {
log.Printf("Response: ENTRY_NOTIFY: %v", result)
ms.opts.Logger.Printf("Response: ENTRY_NOTIFY: %v", result)
}
return result
}
......
......@@ -5,7 +5,6 @@
package fuse
import (
"log"
"syscall"
)
......@@ -25,7 +24,7 @@ func (ms *Server) systemWrite(req *request, header []byte) Status {
req.readResult.Done()
return OK
}
log.Println("trySplice:", err)
ms.opts.Logger.Println("trySplice:", err)
}
sz := req.flatDataSize()
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment