mirror of
https://github.com/netbirdio/gvisor.git
synced 2026-05-22 17:12:49 -07:00
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:
@@ -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()
|
||||
|
||||
|
||||
@@ -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
@@ -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
@@ -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
|
||||
}
|
||||
|
||||
@@ -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.
|
||||
|
||||
@@ -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
File diff suppressed because it is too large
Load Diff
@@ -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)
|
||||
|
||||
@@ -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 {
|
||||
|
||||
@@ -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)
|
||||
|
||||
Reference in New Issue
Block a user