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