diff options
Diffstat (limited to 'runsc/boot')
-rw-r--r-- | runsc/boot/BUILD | 6 | ||||
-rw-r--r-- | runsc/boot/compat.go | 76 | ||||
-rw-r--r-- | runsc/boot/loader.go | 6 |
3 files changed, 88 insertions, 0 deletions
diff --git a/runsc/boot/BUILD b/runsc/boot/BUILD index c1e035d3b..f8f848ebf 100644 --- a/runsc/boot/BUILD +++ b/runsc/boot/BUILD @@ -5,6 +5,7 @@ load("@io_bazel_rules_go//go:def.bzl", "go_library", "go_test") go_library( name = "boot", srcs = [ + "compat.go", "config.go", "controller.go", "debug.go", @@ -21,12 +22,15 @@ go_library( "//runsc:__subpackages__", ], deps = [ + "//pkg/abi", "//pkg/abi/linux", "//pkg/control/server", "//pkg/cpuid", + "//pkg/eventchannel", "//pkg/log", "//pkg/rand", "//pkg/sentry/arch", + "//pkg/sentry/arch:registers_go_proto", "//pkg/sentry/context", "//pkg/sentry/control", "//pkg/sentry/fs", @@ -55,6 +59,7 @@ go_library( "//pkg/sentry/socket/unix", "//pkg/sentry/state", "//pkg/sentry/strace", + "//pkg/sentry/syscalls:unimplemented_syscall_go_proto", "//pkg/sentry/syscalls/linux", "//pkg/sentry/time", "//pkg/sentry/usage", @@ -74,6 +79,7 @@ go_library( "//pkg/urpc", "//runsc/boot/filter", "//runsc/specutils", + "@com_github_golang_protobuf//proto:go_default_library", "@com_github_opencontainers_runtime-spec//specs-go:go_default_library", ], ) diff --git a/runsc/boot/compat.go b/runsc/boot/compat.go new file mode 100644 index 000000000..3250cdcdc --- /dev/null +++ b/runsc/boot/compat.go @@ -0,0 +1,76 @@ +// 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 boot + +import ( + "fmt" + "os" + + "github.com/golang/protobuf/proto" + "gvisor.googlesource.com/gvisor/pkg/abi" + "gvisor.googlesource.com/gvisor/pkg/eventchannel" + "gvisor.googlesource.com/gvisor/pkg/log" + "gvisor.googlesource.com/gvisor/pkg/sentry/arch" + rpb "gvisor.googlesource.com/gvisor/pkg/sentry/arch/registers_go_proto" + "gvisor.googlesource.com/gvisor/pkg/sentry/strace" + spb "gvisor.googlesource.com/gvisor/pkg/sentry/syscalls/unimplemented_syscall_go_proto" +) + +func initCompatLogs(fd int) error { + ce, err := newCompatEmitter(fd) + if err != nil { + return err + } + eventchannel.AddEmitter(ce) + return nil +} + +type compatEmitter struct { + sink *log.BasicLogger + nameMap strace.SyscallMap +} + +func newCompatEmitter(logFD int) (*compatEmitter, error) { + // Always logs to default logger. + nameMap, ok := strace.Lookup(abi.Linux, arch.AMD64) + if !ok { + return nil, fmt.Errorf("amd64 Linux syscall table not found") + } + c := &compatEmitter{sink: log.Log(), nameMap: nameMap} + + if logFD > 0 { + f := os.NewFile(uintptr(logFD), "user log file") + target := log.MultiEmitter{c.sink, log.GoogleEmitter{&log.Writer{Next: f}}} + c.sink = &log.BasicLogger{Level: log.Info, Emitter: target} + } + return c, nil +} + +// Emit implements eventchannel.Emitter. +func (c *compatEmitter) Emit(msg proto.Message) (hangup bool, err error) { + // Only interested in UnimplementedSyscall, skip the rest. + if us, ok := msg.(*spb.UnimplementedSyscall); ok { + regs := us.Registers.GetArch().(*rpb.Registers_Amd64).Amd64 + sysnr := regs.OrigRax + c.sink.Infof("Unsupported syscall: %s, regs: %+v", c.nameMap.Name(uintptr(sysnr)), regs) + } + return false, nil +} + +// Close implements eventchannel.Emitter. +func (c *compatEmitter) Close() error { + c.sink = nil + return nil +} diff --git a/runsc/boot/loader.go b/runsc/boot/loader.go index 60b278295..0a3f67774 100644 --- a/runsc/boot/loader.go +++ b/runsc/boot/loader.go @@ -163,6 +163,8 @@ type Args struct { // TotalMem is the initial amount of total memory to report back to the // container. TotalMem uint64 + // UserLogFD is the file descriptor to write user logs to. + UserLogFD int } // New initializes a new kernel loader configured by spec. @@ -313,6 +315,10 @@ func New(args Args) (*Loader, error) { return nil, fmt.Errorf("failed to create root process: %v", err) } + if err := initCompatLogs(args.UserLogFD); err != nil { + return nil, fmt.Errorf("init compat logs: %v", err) + } + l := &Loader{ k: k, ctrl: ctrl, |