Add debug logging for lisafs.

This change adds debug log messages for lisafs RPC messages just like the p9
package does. This is needed to make lisafs more production ready.

Note that we can not simply call fmt.Sprintf("%+v", message) because fmt
methods accept arguments as interface{} and hence escape them to the heap.
Doing so would cause all messages (which have a temporary lifetime) to
unnecessarily escape to heap hence eroding memory performance. So the String
implementations in this change only escape the struct's fields. Like this, the
struct's fields are heap allocated only when String() is called and in the
common case where debug logging is disabled, String() is not called.

In some cases, there has also been made an effort to not let slice fields
escape because some callers use statically sized arrays as slices which are not
intended to escape.

PiperOrigin-RevId: 428255508
This commit is contained in:
Ayush Ranjan
2022-02-12 16:23:53 -08:00
committed by gVisor bot
parent 0255d313a4
commit 0f7cbc8ecf
10 changed files with 503 additions and 55 deletions
+6
View File
@@ -271,6 +271,12 @@ type Statx struct {
DevMinor uint32
}
// String implements fmt.Stringer.String.
func (s *Statx) String() string {
return fmt.Sprintf("Statx{Mask: %d, Blksize: %d, Attributes: %d, Nlink: %d, UID: %d, GID: %d, Mode: %d, Ino: %d, Size: %d, Blocks: %d, AttributesMask: %d, Atime: %d, Btime: %d, Ctime: %d, Mtime: %d, RdevMajor: %d, RdevMinor: %d, DevMajor: %d, DevMinor: %d}",
s.Mask, s.Blksize, s.Attributes, s.Nlink, s.UID, s.GID, s.Mode, s.Ino, s.Size, s.Blocks, s.AttributesMask, s.Atime, s.Btime, s.Ctime, s.Mtime, s.RdevMajor, s.RdevMinor, s.DevMajor, s.DevMinor)
}
// SizeOfStatx is the size of a Statx struct.
var SizeOfStatx = (*Statx)(nil).SizeBytes()
+6
View File
@@ -15,6 +15,7 @@
package lisafs
import (
"fmt"
"math"
"runtime"
@@ -80,6 +81,11 @@ func (ch *channel) SndRcvMessage(m MID, payloadLen uint32, wantFDs uint8) (MID,
return ch.rcvMsg(rcvDataLen)
}
// String implements fmt.Stringer.String.
func (ch *channel) String() string {
return fmt.Sprintf("channel %p", ch)
}
func (ch *channel) shutdown() {
ch.data.Shutdown()
}
+30 -14
View File
@@ -97,8 +97,11 @@ func NewClient(sock *unet.Socket) (*Client, Inode, error) {
// Mount RPC below.
c.supported = make([]bool, Mount+1)
c.supported[Mount] = true
var mountResp MountResp
if err := c.SndRcvMessage(Mount, 0, NoopMarshal, mountResp.CheckedUnmarshal, nil); err != nil {
var (
mountReq MountReq
mountResp MountResp
)
if err := c.SndRcvMessage(Mount, uint32(mountReq.SizeBytes()), mountReq.MarshalBytes, mountResp.CheckedUnmarshal, nil, mountResp.String, mountResp.String); err != nil {
return nil, Inode{}, err
}
@@ -218,9 +221,12 @@ func (c *Client) Close() {
}
func (c *Client) createChannel() (*channel, error) {
var chanResp ChannelResp
var (
chanReq ChannelReq
chanResp ChannelResp
)
var fds [2]int
if err := c.SndRcvMessage(Channel, 0, NoopMarshal, chanResp.CheckedUnmarshal, fds[:]); err != nil {
if err := c.SndRcvMessage(Channel, uint32(chanReq.SizeBytes()), chanReq.MarshalBytes, chanResp.CheckedUnmarshal, fds[:], chanReq.String, chanResp.String); err != nil {
return nil, err
}
if fds[0] < 0 || fds[1] < 0 {
@@ -277,8 +283,9 @@ func (c *Client) CloseFDBatched(ctx context.Context, fd FDID) {
c.fdsMu.Unlock()
req := CloseReq{FDs: toClose}
var resp CloseResp
ctx.UninterruptibleSleepStart(false)
err := c.SndRcvMessage(Close, uint32(req.SizeBytes()), req.MarshalBytes, NoopUnmarshal, nil)
err := c.SndRcvMessage(Close, uint32(req.SizeBytes()), req.MarshalBytes, resp.CheckedUnmarshal, nil, req.String, resp.String)
ctx.UninterruptibleSleepFinish(false)
if err != nil {
log.Warningf("lisafs: batch closing FDs returned error: %v", err)
@@ -291,8 +298,9 @@ func (c *Client) SyncFDs(ctx context.Context, fds []FDID) error {
return nil
}
req := FsyncReq{FDs: fds}
var resp FsyncResp
ctx.UninterruptibleSleepStart(false)
err := c.SndRcvMessage(FSync, uint32(req.SizeBytes()), req.MarshalBytes, NoopUnmarshal, nil)
err := c.SndRcvMessage(FSync, uint32(req.SizeBytes()), req.MarshalBytes, resp.CheckedUnmarshal, nil, req.String, resp.String)
ctx.UninterruptibleSleepFinish(false)
return err
}
@@ -302,15 +310,11 @@ func (c *Client) SyncFDs(ctx context.Context, fds []FDID) error {
// and invokes respUnmarshal with the response payload. respFDs is populated
// with the received FDs, extra fields are set to -1.
//
// Note that the function arguments intentionally accept marshal.Marshallable
// functions like Marshal{Bytes/Unsafe} and Unmarshal{Bytes/Unsafe} instead of
// directly accepting the marshal.Marshallable interface. Even though just
// accepting marshal.Marshallable is cleaner, it leads to a heap allocation
// (even if that interface variable itself does not escape). In other words,
// implicit conversion to an interface leads to an allocation.
// See messages.go to understand why function arguments are used instead of
// combining these functions into an interface type.
//
// Precondition: reqMarshal and respUnmarshal must be non-nil.
func (c *Client) SndRcvMessage(m MID, payloadLen uint32, reqMarshal func(dst []byte) []byte, respUnmarshal func(src []byte) ([]byte, bool), respFDs []int) error {
// Precondition: function arguments must be non-nil.
func (c *Client) SndRcvMessage(m MID, payloadLen uint32, reqMarshal marshalFunc, respUnmarshal unmarshalFunc, respFDs []int, reqString debugStringer, respString debugStringer) error {
if !c.IsSupported(m) {
return unix.EOPNOTSUPP
}
@@ -328,6 +332,8 @@ func (c *Client) SndRcvMessage(m MID, payloadLen uint32, reqMarshal func(dst []b
comm := c.acquireCommunicator()
defer c.releaseCommunicator(comm)
debugf("send", comm, reqString)
// Marshal the request into comm's payload buffer and make the RPC.
reqMarshal(comm.PayloadBuf(payloadLen))
respM, respPayloadLen, err := comm.SndRcvMessage(m, payloadLen, uint8(wantFDs))
@@ -363,6 +369,7 @@ func (c *Client) SndRcvMessage(m MID, payloadLen uint32, reqMarshal func(dst []b
closeFDs(respFDs)
var resp ErrorResp
resp.UnmarshalUnsafe(comm.PayloadBuf(respPayloadLen))
debugf("recv", comm, resp.String)
return unix.Errno(resp.errno)
}
if respM != m {
@@ -376,9 +383,18 @@ func (c *Client) SndRcvMessage(m MID, payloadLen uint32, reqMarshal func(dst []b
log.Warningf("server response unmarshalling for %d message failed", respM)
return unix.EIO
}
debugf("recv", comm, respString)
return nil
}
func debugf(action string, comm Communicator, debugMsg debugStringer) {
// Replicate the log.IsLogging(log.Debug) check to avoid having to call
// debugMsg() on the hot path.
if log.IsLogging(log.Debug) {
log.Debugf("%s [%s] %s", action, comm, debugMsg())
}
}
// Postcondition: releaseCommunicator() must be called on the returned value.
func (c *Client) acquireCommunicator() Communicator {
// Prefer using channel over socket because:
+36 -31
View File
@@ -66,9 +66,10 @@ func (f *ClientFD) CloseBatched(ctx context.Context) {
func (f *ClientFD) Close(ctx context.Context) error {
fdArr := [1]FDID{f.fd}
req := CloseReq{FDs: fdArr[:]}
var resp CloseResp
ctx.UninterruptibleSleepStart(false)
err := f.client.SndRcvMessage(Close, uint32(req.SizeBytes()), req.MarshalBytes, NoopUnmarshal, nil)
err := f.client.SndRcvMessage(Close, uint32(req.SizeBytes()), req.MarshalBytes, resp.CheckedUnmarshal, nil, req.String, resp.String)
ctx.UninterruptibleSleepFinish(false)
return err
}
@@ -82,7 +83,7 @@ func (f *ClientFD) OpenAt(ctx context.Context, flags uint32) (FDID, int, error)
var respFD [1]int
var resp OpenAtResp
ctx.UninterruptibleSleepStart(false)
err := f.client.SndRcvMessage(OpenAt, uint32(req.SizeBytes()), req.MarshalUnsafe, resp.CheckedUnmarshal, respFD[:])
err := f.client.SndRcvMessage(OpenAt, uint32(req.SizeBytes()), req.MarshalUnsafe, resp.CheckedUnmarshal, respFD[:], req.String, resp.String)
ctx.UninterruptibleSleepFinish(false)
return resp.OpenFD, respFD[0], err
}
@@ -100,7 +101,7 @@ func (f *ClientFD) OpenCreateAt(ctx context.Context, name string, flags uint32,
var respFD [1]int
var resp OpenCreateAtResp
ctx.UninterruptibleSleepStart(false)
err := f.client.SndRcvMessage(OpenCreateAt, uint32(req.SizeBytes()), req.MarshalBytes, resp.CheckedUnmarshal, respFD[:])
err := f.client.SndRcvMessage(OpenCreateAt, uint32(req.SizeBytes()), req.MarshalBytes, resp.CheckedUnmarshal, respFD[:], req.String, resp.String)
ctx.UninterruptibleSleepFinish(false)
return resp.Child, resp.NewFD, respFD[0], err
}
@@ -109,7 +110,7 @@ func (f *ClientFD) OpenCreateAt(ctx context.Context, name string, flags uint32,
func (f *ClientFD) StatTo(ctx context.Context, stat *linux.Statx) error {
req := StatReq{FD: f.fd}
ctx.UninterruptibleSleepStart(false)
err := f.client.SndRcvMessage(FStat, uint32(req.SizeBytes()), req.MarshalUnsafe, stat.CheckedUnmarshal, nil)
err := f.client.SndRcvMessage(FStat, uint32(req.SizeBytes()), req.MarshalUnsafe, stat.CheckedUnmarshal, nil, req.String, stat.String)
ctx.UninterruptibleSleepFinish(false)
return err
}
@@ -117,8 +118,9 @@ func (f *ClientFD) StatTo(ctx context.Context, stat *linux.Statx) error {
// Sync makes the Fsync RPC.
func (f *ClientFD) Sync(ctx context.Context) error {
req := FsyncReq{FDs: []FDID{f.fd}}
var resp FsyncResp
ctx.UninterruptibleSleepStart(false)
err := f.client.SndRcvMessage(FSync, uint32(req.SizeBytes()), req.MarshalBytes, NoopUnmarshal, nil)
err := f.client.SndRcvMessage(FSync, uint32(req.SizeBytes()), req.MarshalBytes, resp.CheckedUnmarshal, nil, req.String, resp.String)
ctx.UninterruptibleSleepFinish(false)
return err
}
@@ -181,7 +183,7 @@ func (f *ClientFD) Read(ctx context.Context, dst []byte, offset uint64) (uint64,
// PReadResp.CheckedUnmarshal expects this to be set.
resp.Buf = buf
ctx.UninterruptibleSleepStart(false)
err := f.client.SndRcvMessage(PRead, uint32(req.SizeBytes()), req.MarshalUnsafe, resp.CheckedUnmarshal, nil)
err := f.client.SndRcvMessage(PRead, uint32(req.SizeBytes()), req.MarshalUnsafe, resp.CheckedUnmarshal, nil, req.String, resp.String)
ctx.UninterruptibleSleepFinish(false)
return uint64(resp.NumBytes), err
})
@@ -205,7 +207,7 @@ func (f *ClientFD) Write(ctx context.Context, src []byte, offset uint64) (uint64
var resp PWriteResp
ctx.UninterruptibleSleepStart(false)
err := f.client.SndRcvMessage(PWrite, uint32(req.SizeBytes()), req.MarshalBytes, resp.CheckedUnmarshal, nil)
err := f.client.SndRcvMessage(PWrite, uint32(req.SizeBytes()), req.MarshalBytes, resp.CheckedUnmarshal, nil, req.String, resp.String)
ctx.UninterruptibleSleepFinish(false)
return resp.Count, err
})
@@ -222,7 +224,7 @@ func (f *ClientFD) MkdirAt(ctx context.Context, name string, mode linux.FileMode
var resp MkdirAtResp
ctx.UninterruptibleSleepStart(false)
err := f.client.SndRcvMessage(MkdirAt, uint32(req.SizeBytes()), req.MarshalBytes, resp.CheckedUnmarshal, nil)
err := f.client.SndRcvMessage(MkdirAt, uint32(req.SizeBytes()), req.MarshalBytes, resp.CheckedUnmarshal, nil, req.String, resp.String)
ctx.UninterruptibleSleepFinish(false)
return resp.ChildDir, err
}
@@ -239,7 +241,7 @@ func (f *ClientFD) SymlinkAt(ctx context.Context, name, target string, uid UID,
var resp SymlinkAtResp
ctx.UninterruptibleSleepStart(false)
err := f.client.SndRcvMessage(SymlinkAt, uint32(req.SizeBytes()), req.MarshalBytes, resp.CheckedUnmarshal, nil)
err := f.client.SndRcvMessage(SymlinkAt, uint32(req.SizeBytes()), req.MarshalBytes, resp.CheckedUnmarshal, nil, req.String, resp.String)
ctx.UninterruptibleSleepFinish(false)
return resp.Symlink, err
}
@@ -254,7 +256,7 @@ func (f *ClientFD) LinkAt(ctx context.Context, targetFD FDID, name string) (Inod
var resp LinkAtResp
ctx.UninterruptibleSleepStart(false)
err := f.client.SndRcvMessage(LinkAt, uint32(req.SizeBytes()), req.MarshalBytes, resp.CheckedUnmarshal, nil)
err := f.client.SndRcvMessage(LinkAt, uint32(req.SizeBytes()), req.MarshalBytes, resp.CheckedUnmarshal, nil, req.String, resp.String)
ctx.UninterruptibleSleepFinish(false)
return resp.Link, err
}
@@ -272,7 +274,7 @@ func (f *ClientFD) MknodAt(ctx context.Context, name string, mode linux.FileMode
var resp MknodAtResp
ctx.UninterruptibleSleepStart(false)
err := f.client.SndRcvMessage(MknodAt, uint32(req.SizeBytes()), req.MarshalBytes, resp.CheckedUnmarshal, nil)
err := f.client.SndRcvMessage(MknodAt, uint32(req.SizeBytes()), req.MarshalBytes, resp.CheckedUnmarshal, nil, req.String, resp.String)
ctx.UninterruptibleSleepFinish(false)
return resp.Child, err
}
@@ -298,7 +300,7 @@ func (f *ClientFD) SetStat(ctx context.Context, stat *linux.Statx) (uint32, erro
var resp SetStatResp
ctx.UninterruptibleSleepStart(false)
err := f.client.SndRcvMessage(SetStat, uint32(req.SizeBytes()), req.MarshalUnsafe, resp.CheckedUnmarshal, nil)
err := f.client.SndRcvMessage(SetStat, uint32(req.SizeBytes()), req.MarshalUnsafe, resp.CheckedUnmarshal, nil, req.String, resp.String)
ctx.UninterruptibleSleepFinish(false)
return resp.FailureMask, unix.Errno(resp.FailureErrNo), err
}
@@ -312,7 +314,7 @@ func (f *ClientFD) WalkMultiple(ctx context.Context, names []string) (WalkStatus
var resp WalkResp
ctx.UninterruptibleSleepStart(false)
err := f.client.SndRcvMessage(Walk, uint32(req.SizeBytes()), req.MarshalBytes, resp.CheckedUnmarshal, nil)
err := f.client.SndRcvMessage(Walk, uint32(req.SizeBytes()), req.MarshalBytes, resp.CheckedUnmarshal, nil, req.String, resp.String)
ctx.UninterruptibleSleepFinish(false)
return resp.Status, resp.Inodes, err
}
@@ -327,7 +329,7 @@ func (f *ClientFD) Walk(ctx context.Context, name string) (Inode, error) {
var inode [1]Inode
resp := WalkResp{Inodes: inode[:]}
ctx.UninterruptibleSleepStart(false)
err := f.client.SndRcvMessage(Walk, uint32(req.SizeBytes()), req.MarshalBytes, resp.CheckedUnmarshal, nil)
err := f.client.SndRcvMessage(Walk, uint32(req.SizeBytes()), req.MarshalBytes, resp.CheckedUnmarshal, nil, req.String, resp.String)
ctx.UninterruptibleSleepFinish(false)
if err != nil {
return Inode{}, err
@@ -363,7 +365,7 @@ func (f *ClientFD) WalkStat(ctx context.Context, names []string) ([]linux.Statx,
var resp WalkStatResp
ctx.UninterruptibleSleepStart(false)
err := f.client.SndRcvMessage(WalkStat, uint32(req.SizeBytes()), req.MarshalBytes, resp.CheckedUnmarshal, nil)
err := f.client.SndRcvMessage(WalkStat, uint32(req.SizeBytes()), req.MarshalBytes, resp.CheckedUnmarshal, nil, req.String, resp.String)
ctx.UninterruptibleSleepFinish(false)
return resp.Stats, err
}
@@ -372,7 +374,7 @@ func (f *ClientFD) WalkStat(ctx context.Context, names []string) ([]linux.Statx,
func (f *ClientFD) StatFSTo(ctx context.Context, statFS *StatFS) error {
req := FStatFSReq{FD: f.fd}
ctx.UninterruptibleSleepStart(false)
err := f.client.SndRcvMessage(FStatFS, uint32(req.SizeBytes()), req.MarshalUnsafe, statFS.CheckedUnmarshal, nil)
err := f.client.SndRcvMessage(FStatFS, uint32(req.SizeBytes()), req.MarshalUnsafe, statFS.CheckedUnmarshal, nil, req.String, statFS.String)
ctx.UninterruptibleSleepFinish(false)
return err
}
@@ -385,8 +387,9 @@ func (f *ClientFD) Allocate(ctx context.Context, mode, offset, length uint64) er
Offset: offset,
Length: length,
}
var resp FAllocateResp
ctx.UninterruptibleSleepStart(false)
err := f.client.SndRcvMessage(FAllocate, uint32(req.SizeBytes()), req.MarshalUnsafe, NoopUnmarshal, nil)
err := f.client.SndRcvMessage(FAllocate, uint32(req.SizeBytes()), req.MarshalUnsafe, resp.CheckedUnmarshal, nil, req.String, resp.String)
ctx.UninterruptibleSleepFinish(false)
return err
}
@@ -396,7 +399,7 @@ func (f *ClientFD) ReadLinkAt(ctx context.Context) (string, error) {
req := ReadLinkAtReq{FD: f.fd}
var resp ReadLinkAtResp
ctx.UninterruptibleSleepStart(false)
err := f.client.SndRcvMessage(ReadLinkAt, uint32(req.SizeBytes()), req.MarshalUnsafe, resp.CheckedUnmarshal, nil)
err := f.client.SndRcvMessage(ReadLinkAt, uint32(req.SizeBytes()), req.MarshalUnsafe, resp.CheckedUnmarshal, nil, req.String, resp.String)
ctx.UninterruptibleSleepFinish(false)
return string(resp.Target), err
}
@@ -408,8 +411,9 @@ func (f *ClientFD) Flush(ctx context.Context) error {
return nil
}
req := FlushReq{FD: f.fd}
var resp FlushResp
ctx.UninterruptibleSleepStart(false)
err := f.client.SndRcvMessage(Flush, uint32(req.SizeBytes()), req.MarshalUnsafe, NoopUnmarshal, nil)
err := f.client.SndRcvMessage(Flush, uint32(req.SizeBytes()), req.MarshalUnsafe, resp.CheckedUnmarshal, nil, req.String, resp.String)
ctx.UninterruptibleSleepFinish(false)
return err
}
@@ -417,9 +421,10 @@ func (f *ClientFD) Flush(ctx context.Context) error {
// Connect makes the Connect RPC.
func (f *ClientFD) Connect(ctx context.Context, sockType linux.SockType) (int, error) {
req := ConnectReq{FD: f.fd, SockType: uint32(sockType)}
var resp ConnectResp
var sockFD [1]int
ctx.UninterruptibleSleepStart(false)
err := f.client.SndRcvMessage(Connect, uint32(req.SizeBytes()), req.MarshalUnsafe, NoopUnmarshal, sockFD[:])
err := f.client.SndRcvMessage(Connect, uint32(req.SizeBytes()), req.MarshalUnsafe, resp.CheckedUnmarshal, sockFD[:], req.String, resp.String)
ctx.UninterruptibleSleepFinish(false)
if err == nil && sockFD[0] < 0 {
err = unix.EBADF
@@ -434,9 +439,9 @@ func (f *ClientFD) UnlinkAt(ctx context.Context, name string, flags uint32) erro
Name: SizedString(name),
Flags: primitive.Uint32(flags),
}
var resp UnlinkAtResp
ctx.UninterruptibleSleepStart(false)
err := f.client.SndRcvMessage(UnlinkAt, uint32(req.SizeBytes()), req.MarshalBytes, NoopUnmarshal, nil)
err := f.client.SndRcvMessage(UnlinkAt, uint32(req.SizeBytes()), req.MarshalBytes, resp.CheckedUnmarshal, nil, req.String, resp.String)
ctx.UninterruptibleSleepFinish(false)
return err
}
@@ -450,9 +455,9 @@ func (f *ClientFD) RenameAt(ctx context.Context, oldName string, newDirFD FDID,
NewDir: newDirFD,
NewName: SizedString(newName),
}
var resp RenameAtResp
ctx.UninterruptibleSleepStart(false)
err := f.client.SndRcvMessage(RenameAt, uint32(req.SizeBytes()), req.MarshalBytes, NoopUnmarshal, nil)
err := f.client.SndRcvMessage(RenameAt, uint32(req.SizeBytes()), req.MarshalBytes, resp.CheckedUnmarshal, nil, req.String, resp.String)
ctx.UninterruptibleSleepFinish(false)
return err
}
@@ -466,7 +471,7 @@ func (f *ClientFD) Getdents64(ctx context.Context, count int32) ([]Dirent64, err
var resp Getdents64Resp
ctx.UninterruptibleSleepStart(false)
err := f.client.SndRcvMessage(Getdents64, uint32(req.SizeBytes()), req.MarshalUnsafe, resp.CheckedUnmarshal, nil)
err := f.client.SndRcvMessage(Getdents64, uint32(req.SizeBytes()), req.MarshalUnsafe, resp.CheckedUnmarshal, nil, req.String, resp.String)
ctx.UninterruptibleSleepFinish(false)
return resp.Dirents, err
}
@@ -480,7 +485,7 @@ func (f *ClientFD) ListXattr(ctx context.Context, size uint64) ([]string, error)
var resp FListXattrResp
ctx.UninterruptibleSleepStart(false)
err := f.client.SndRcvMessage(FListXattr, uint32(req.SizeBytes()), req.MarshalUnsafe, resp.CheckedUnmarshal, nil)
err := f.client.SndRcvMessage(FListXattr, uint32(req.SizeBytes()), req.MarshalUnsafe, resp.CheckedUnmarshal, nil, req.String, resp.String)
ctx.UninterruptibleSleepFinish(false)
return resp.Xattrs, err
}
@@ -495,7 +500,7 @@ func (f *ClientFD) GetXattr(ctx context.Context, name string, size uint64) (stri
var resp FGetXattrResp
ctx.UninterruptibleSleepStart(false)
err := f.client.SndRcvMessage(FGetXattr, uint32(req.SizeBytes()), req.MarshalBytes, resp.CheckedUnmarshal, nil)
err := f.client.SndRcvMessage(FGetXattr, uint32(req.SizeBytes()), req.MarshalBytes, resp.CheckedUnmarshal, nil, req.String, resp.String)
ctx.UninterruptibleSleepFinish(false)
return string(resp.Value), err
}
@@ -508,9 +513,9 @@ func (f *ClientFD) SetXattr(ctx context.Context, name string, value string, flag
Value: SizedString(value),
Flags: primitive.Uint32(flags),
}
var resp FSetXattrResp
ctx.UninterruptibleSleepStart(false)
err := f.client.SndRcvMessage(FSetXattr, uint32(req.SizeBytes()), req.MarshalBytes, NoopUnmarshal, nil)
err := f.client.SndRcvMessage(FSetXattr, uint32(req.SizeBytes()), req.MarshalBytes, resp.CheckedUnmarshal, nil, req.String, resp.String)
ctx.UninterruptibleSleepFinish(false)
return err
}
@@ -521,9 +526,9 @@ func (f *ClientFD) RemoveXattr(ctx context.Context, name string) error {
FD: f.fd,
Name: SizedString(name),
}
var resp FRemoveXattrResp
ctx.UninterruptibleSleepStart(false)
err := f.client.SndRcvMessage(FRemoveXattr, uint32(req.SizeBytes()), req.MarshalBytes, NoopUnmarshal, nil)
err := f.client.SndRcvMessage(FRemoveXattr, uint32(req.SizeBytes()), req.MarshalBytes, resp.CheckedUnmarshal, nil, req.String, resp.String)
ctx.UninterruptibleSleepFinish(false)
return err
}
+7 -1
View File
@@ -14,11 +14,17 @@
package lisafs
import "golang.org/x/sys/unix"
import (
"fmt"
"golang.org/x/sys/unix"
)
// Communicator is a server side utility which represents exactly how the
// server is communicating with the client.
type Communicator interface {
fmt.Stringer
// PayloadBuf returns a slice to the payload section of its internal buffer
// where the message can be marshalled. The handlers should use this to
// populate the payload buffer with the message.
+4 -3
View File
@@ -118,8 +118,9 @@ func TestStartUp(t *testing.T) {
func TestUnsupportedMessage(t *testing.T) {
unsupportedM := lisafs.MID(len(handlers))
var em lisafs.EmptyMessage
runServerClient(t, func(c *lisafs.Client) {
if err := c.SndRcvMessage(unsupportedM, 0, lisafs.NoopMarshal, lisafs.NoopUnmarshal, nil); err != unix.EOPNOTSUPP {
if err := c.SndRcvMessage(unsupportedM, uint32(em.SizeBytes()), em.MarshalBytes, em.CheckedUnmarshal, nil, em.String, em.String); err != unix.EOPNOTSUPP {
t.Errorf("expected EOPNOTSUPP but got err: %v", err)
}
})
@@ -154,7 +155,7 @@ func TestStress(t *testing.T) {
req.Randomize(100)
var resp lisafs.MsgDynamic
if err := c.SndRcvMessage(dynamicMsgID, uint32(req.SizeBytes()), req.MarshalBytes, resp.CheckedUnmarshal, nil); err != nil {
if err := c.SndRcvMessage(dynamicMsgID, uint32(req.SizeBytes()), req.MarshalBytes, resp.CheckedUnmarshal, nil, req.String, resp.String); err != nil {
t.Errorf("SndRcvMessage: received unexpected error %v", err)
return
}
@@ -198,7 +199,7 @@ func BenchmarkSendRecv(b *testing.B) {
var recvV lisafs.P9Version
runServerClient(b, func(c *lisafs.Client) {
for i := 0; i < b.N; i++ {
if err := c.SndRcvMessage(versionMsgID, uint32(sendV.SizeBytes()), sendV.MarshalBytes, recvV.CheckedUnmarshal, nil); err != nil {
if err := c.SndRcvMessage(versionMsgID, uint32(sendV.SizeBytes()), sendV.MarshalBytes, recvV.CheckedUnmarshal, nil, sendV.String, recvV.String); err != nil {
b.Fatalf("unexpected error occurred: %v", err)
}
}
+396 -5
View File
File diff suppressed because it is too large Load Diff
+11
View File
@@ -15,6 +15,7 @@
package lisafs
import (
"fmt"
"math/rand"
"gvisor.dev/gvisor/pkg/marshal/primitive"
@@ -46,6 +47,11 @@ type MsgDynamic struct {
Arr []MsgSimple
}
// String implements fmt.Stringer.String.
func (m *MsgDynamic) String() string {
return fmt.Sprintf("MsgDynamic{N: %d, Arr: %v}", m.N, m.Arr)
}
// SizeBytes implements marshal.Marshallable.SizeBytes.
func (m *MsgDynamic) SizeBytes() int {
return m.N.SizeBytes() +
@@ -98,6 +104,11 @@ type P9Version struct {
Version string
}
// String implements fmt.Stringer.String.
func (v *P9Version) String() string {
return fmt.Sprintf("P9Version{MSize: %d, Version: %s}", v.MSize, v.Version)
}
// SizeBytes implements marshal.Marshallable.SizeBytes.
func (v *P9Version) SizeBytes() int {
return (*primitive.Uint32)(nil).SizeBytes() + (*primitive.Uint16)(nil).SizeBytes() + len(v.Version)
+6
View File
@@ -15,6 +15,7 @@
package lisafs
import (
"fmt"
"io"
"golang.org/x/sys/unix"
@@ -89,6 +90,11 @@ func (s *sockCommunicator) SndRcvMessage(m MID, payloadLen uint32, wantFDs uint8
return s.rcvMsg(wantFDs)
}
// String implements fmt.Stringer.String.
func (s *sockCommunicator) String() string {
return fmt.Sprintf("sockComm %d", s.sock.FD())
}
// sndPrepopulatedMsg assumes that s.buf has already been populated with
// `payloadLen` bytes of data.
func (s *sockCommunicator) sndPrepopulatedMsg(m MID, payloadLen uint32, fds []int) error {
+1 -1
View File
@@ -195,7 +195,7 @@ func TestSndRcvMessageNoPayload(t *testing.T) {
})
}
func checkMessageReceive(t *testing.T, comm *sockCommunicator, wantM MID, wantMsg interface{}) {
func checkMessageReceive(t *testing.T, comm *sockCommunicator, wantM MID, wantMsg marshal.Marshallable) {
gotM, payloadLen, err := comm.rcvMsg(0)
if err != nil {
t.Fatalf("readMessageFrom failed: %v", err)