From 0ce9c81b416494e3c3da793c278dfc767341fa6d Mon Sep 17 00:00:00 2001 From: Zhaozhong Ni Date: Fri, 4 May 2018 13:55:06 -0700 Subject: sentry: capture CPU usage metadata for save. PiperOrigin-RevId: 195466647 Change-Id: Ib5ca815f7b64a4881441e58567adedf344b206f1 --- pkg/sentry/state/BUILD | 2 ++ pkg/sentry/state/state.go | 6 +++++- pkg/sentry/state/state_metadata.go | 16 ++++++++++++++++ pkg/sentry/state/state_unsafe.go | 33 +++++++++++++++++++++++++++++++++ 4 files changed, 56 insertions(+), 1 deletion(-) create mode 100644 pkg/sentry/state/state_unsafe.go (limited to 'pkg/sentry') diff --git a/pkg/sentry/state/BUILD b/pkg/sentry/state/BUILD index 7148df395..9bd98f445 100644 --- a/pkg/sentry/state/BUILD +++ b/pkg/sentry/state/BUILD @@ -7,10 +7,12 @@ go_library( srcs = [ "state.go", "state_metadata.go", + "state_unsafe.go", ], importpath = "gvisor.googlesource.com/gvisor/pkg/sentry/state", visibility = ["//pkg/sentry:internal"], deps = [ + "//pkg/abi/linux", "//pkg/log", "//pkg/sentry/inet", "//pkg/sentry/kernel", diff --git a/pkg/sentry/state/state.go b/pkg/sentry/state/state.go index 5bec4e018..c306091da 100644 --- a/pkg/sentry/state/state.go +++ b/pkg/sentry/state/state.go @@ -27,6 +27,8 @@ import ( "gvisor.googlesource.com/gvisor/pkg/state/statefile" ) +var previousMetadata map[string]string + // ErrStateFile is returned when the state file cannot be opened. type ErrStateFile struct { err error @@ -103,11 +105,13 @@ type LoadOpts struct { // Load loads the given kernel, setting the provided platform and stack. func (opts LoadOpts) Load(k *kernel.Kernel, p platform.Platform, n inet.Stack) error { // Open the file. - r, _, err := statefile.NewReader(opts.Source, opts.Key) + r, m, err := statefile.NewReader(opts.Source, opts.Key) if err != nil { return ErrStateFile{err} } + previousMetadata = m + // Restore the Kernel object graph. return k.LoadFrom(r, p, n) } diff --git a/pkg/sentry/state/state_metadata.go b/pkg/sentry/state/state_metadata.go index ac374f428..b6d3dbcb4 100644 --- a/pkg/sentry/state/state_metadata.go +++ b/pkg/sentry/state/state_metadata.go @@ -17,13 +17,29 @@ package state import ( "fmt" "time" + + "gvisor.googlesource.com/gvisor/pkg/log" ) // The save metadata keys for timestamp. const ( + cpuUsage = "cpu_usage" metadataTimestamp = "timestamp" ) func addSaveMetadata(m map[string]string) { + t, err := cpuTime() + if err != nil { + log.Warningf("Error getting cpu time: %v", err) + } + if previousMetadata != nil { + p, err := time.ParseDuration(previousMetadata[cpuUsage]) + if err != nil { + log.Warningf("Error parsing previous runs' cpu time: %v", err) + } + t += p + } + m[cpuUsage] = t.String() + m[metadataTimestamp] = fmt.Sprintf("%v", time.Now()) } diff --git a/pkg/sentry/state/state_unsafe.go b/pkg/sentry/state/state_unsafe.go new file mode 100644 index 000000000..53814ef70 --- /dev/null +++ b/pkg/sentry/state/state_unsafe.go @@ -0,0 +1,33 @@ +// Copyright 2018 Google Inc. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package state + +import ( + "fmt" + "syscall" + "time" + "unsafe" + + "gvisor.googlesource.com/gvisor/pkg/abi/linux" +) + +func cpuTime() (time.Duration, error) { + var ts syscall.Timespec + _, _, errno := syscall.RawSyscall(syscall.SYS_CLOCK_GETTIME, uintptr(linux.CLOCK_PROCESS_CPUTIME_ID), uintptr(unsafe.Pointer(&ts)), 0) + if errno != 0 { + return 0, fmt.Errorf("failed calling clock_gettime(CLOCK_PROCESS_CPUTIME_ID): errno=%d", errno) + } + return time.Duration(ts.Nano()), nil +} -- cgit v1.2.3