diff --git a/pkg/sentry/control/BUILD b/pkg/sentry/control/BUILD index cfb33a398..3d72b65a3 100644 --- a/pkg/sentry/control/BUILD +++ b/pkg/sentry/control/BUILD @@ -35,6 +35,7 @@ go_library( "//pkg/sentry/fs/host", "//pkg/sentry/fs/user", "//pkg/sentry/fsimpl/host", + "//pkg/sentry/fsmetric", "//pkg/sentry/kernel", "//pkg/sentry/kernel/auth", "//pkg/sentry/kernel/time", diff --git a/pkg/sentry/control/usage.go b/pkg/sentry/control/usage.go index cc78d3f45..1ed39621d 100644 --- a/pkg/sentry/control/usage.go +++ b/pkg/sentry/control/usage.go @@ -15,11 +15,13 @@ package control import ( + "encoding/json" "fmt" "os" "runtime" "golang.org/x/sys/unix" + "gvisor.dev/gvisor/pkg/sentry/fsmetric" "gvisor.dev/gvisor/pkg/sentry/kernel" "gvisor.dev/gvisor/pkg/sentry/usage" "gvisor.dev/gvisor/pkg/urpc" @@ -168,6 +170,30 @@ func NewMemoryUsageRecord(usageFile, platformFile os.File) (*MemoryUsageRecord, return &m, nil } +// GetFileIoStats writes the read times in nanoseconds to out. +func (*Usage) GetFileIoStats(_ *struct{}, out *string) error { + fileIoStats := struct { + // The total amount of time spent reading. The map maps gopher prefixes + // to the total time spent reading. Times not included in a known prefix + // are placed in the "/" prefix. + ReadWait map[string]uint64 `json:"ReadWait"` + // The total amount of time spent reading. The map maps gopher prefixes + // to the total time spent reading. Times not included in a known prefix + // are placed in the "/" prefix. + ReadWait9P map[string]uint64 `json:"ReadWait9P"` + }{ + ReadWait: map[string]uint64{"/": fsmetric.ReadWait.Value()}, + ReadWait9P: map[string]uint64{"/": fsmetric.GoferReadWait9P.Value()}, + } + + m, err := json.Marshal(fileIoStats) + if err != nil { + return err + } + *out = string(m) + return nil +} + func finalizer(m *MemoryUsageRecord) { unix.RawSyscall(unix.SYS_MUNMAP, m.mmap, usage.RTMemoryStatsSize, 0) }