diff options
Diffstat (limited to 'runsc/boot/compat.go')
-rw-r--r-- | runsc/boot/compat.go | 76 |
1 files changed, 76 insertions, 0 deletions
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 +} |