diff options
Diffstat (limited to 'pkg/sentry/fs/gofer')
-rw-r--r-- | pkg/sentry/fs/gofer/file.go | 43 |
1 files changed, 31 insertions, 12 deletions
diff --git a/pkg/sentry/fs/gofer/file.go b/pkg/sentry/fs/gofer/file.go index 7a6dabba8..631cc80ae 100644 --- a/pkg/sentry/fs/gofer/file.go +++ b/pkg/sentry/fs/gofer/file.go @@ -17,6 +17,7 @@ package gofer import ( "fmt" "syscall" + "time" "gvisor.googlesource.com/gvisor/pkg/log" "gvisor.googlesource.com/gvisor/pkg/metric" @@ -32,11 +33,13 @@ import ( ) var ( - opensWX = metric.MustCreateNewUint64Metric("/gofer/opened_write_execute_file", true /* sync */, "Number of times a writable+executable file was opened from a gofer.") - opens9P = metric.MustCreateNewUint64Metric("/gofer/opens_9p", false /* sync */, "Number of times a 9P file was opened from a gofer.") - opensHost = metric.MustCreateNewUint64Metric("/gofer/opens_host", false /* sync */, "Number of times a host file was opened from a gofer.") - reads9P = metric.MustCreateNewUint64Metric("/gofer/reads_9p", false /* sync */, "Number of 9P file reads from a gofer.") - readsHost = metric.MustCreateNewUint64Metric("/gofer/reads_host", false /* sync */, "Number of host file reads from a gofer.") + opensWX = metric.MustCreateNewUint64Metric("/gofer/opened_write_execute_file", true /* sync */, "Number of times a writable+executable file was opened from a gofer.") + opens9P = metric.MustCreateNewUint64Metric("/gofer/opens_9p", false /* sync */, "Number of times a 9P file was opened from a gofer.") + opensHost = metric.MustCreateNewUint64Metric("/gofer/opens_host", false /* sync */, "Number of times a host file was opened from a gofer.") + reads9P = metric.MustCreateNewUint64Metric("/gofer/reads_9p", false /* sync */, "Number of 9P file reads from a gofer.") + readWait9P = metric.MustCreateNewUint64Metric("/gofer/read_wait_9p", false /* sync */, "Time waiting on 9P file reads from a gofer, in nanoseconds.") + readsHost = metric.MustCreateNewUint64Metric("/gofer/reads_host", false /* sync */, "Number of host file reads from a gofer.") + readWaitHost = metric.MustCreateNewUint64Metric("/gofer/read_wait_host", false /* sync */, "Time waiting on host file reads from a gofer, in nanoseconds.") ) // fileOperations implements fs.FileOperations for a remote file system. @@ -232,22 +235,38 @@ func (f *fileOperations) Write(ctx context.Context, file *fs.File, src usermem.I return src.CopyInTo(ctx, f.handles.readWriterAt(ctx, offset)) } +// incrementReadCounters increments the read counters for the read starting at the given time. We +// use this function rather than using a defer in Read() to avoid the performance hit of defer. +func (f *fileOperations) incrementReadCounters(start time.Time) { + if f.handles.Host != nil { + readsHost.Increment() + fs.IncrementWait(readWaitHost, start) + } else { + reads9P.Increment() + fs.IncrementWait(readWait9P, start) + } +} + // Read implements fs.FileOperations.Read. func (f *fileOperations) Read(ctx context.Context, file *fs.File, dst usermem.IOSequence, offset int64) (int64, error) { + var start time.Time + if fs.RecordWaitTime { + start = time.Now() + } if fs.IsDir(file.Dirent.Inode.StableAttr) { // Not all remote file systems enforce this so this client does. + f.incrementReadCounters(start) return 0, syserror.EISDIR } - if f.handles.Host != nil { - readsHost.Increment() - } else { - reads9P.Increment() - } if f.inodeOperations.session().cachePolicy.useCachingInodeOps(file.Dirent.Inode) { - return f.inodeOperations.cachingInodeOps.Read(ctx, file, dst, offset) + n, err := f.inodeOperations.cachingInodeOps.Read(ctx, file, dst, offset) + f.incrementReadCounters(start) + return n, err } - return dst.CopyOutFrom(ctx, f.handles.readWriterAt(ctx, offset)) + n, err := dst.CopyOutFrom(ctx, f.handles.readWriterAt(ctx, offset)) + f.incrementReadCounters(start) + return n, err } // Fsync implements fs.FileOperations.Fsync. |