137 lines
4.1 KiB
Go
137 lines
4.1 KiB
Go
// Copyright 2019 The gVisor Authors.
|
|
//
|
|
// 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 control
|
|
|
|
import (
|
|
"fmt"
|
|
"sync/atomic"
|
|
|
|
"gvisor.dev/gvisor/pkg/log"
|
|
"gvisor.dev/gvisor/pkg/sentry/strace"
|
|
"gvisor.dev/gvisor/pkg/tcpip/link/sniffer"
|
|
)
|
|
|
|
// LoggingArgs are the arguments to use for changing the logging
|
|
// level and strace list.
|
|
type LoggingArgs struct {
|
|
// SetLevel is a flag used to indicate that we should update
|
|
// the logging level. We should be able to change the strace
|
|
// list without affecting the logging level and vice versa.
|
|
SetLevel bool
|
|
|
|
// Level is the log level that will be set if SetLevel is true.
|
|
Level log.Level
|
|
|
|
// SetLogPackets indicates that we should update the log packets flag.
|
|
SetLogPackets bool
|
|
|
|
// LogPackets is the actual value to set for LogPackets.
|
|
// SetLogPackets must be enabled to indicate that we're changing
|
|
// the value.
|
|
LogPackets bool
|
|
|
|
// SetStrace is a flag used to indicate that strace related
|
|
// arguments were passed in.
|
|
SetStrace bool
|
|
|
|
// EnableStrace is a flag from the CLI that specifies whether to
|
|
// enable strace at all. If this flag is false then a completely
|
|
// pristine copy of the syscall table will be swapped in. This
|
|
// approach is used to remain consistent with an empty strace
|
|
// whitelist meaning trace all system calls.
|
|
EnableStrace bool
|
|
|
|
// Strace is the whitelist of syscalls to trace to log. If this
|
|
// and StraceEventWhitelist are empty trace all system calls.
|
|
StraceWhitelist []string
|
|
|
|
// SetEventStrace is a flag used to indicate that event strace
|
|
// related arguments were passed in.
|
|
SetEventStrace bool
|
|
|
|
// StraceEventWhitelist is the whitelist of syscalls to trace
|
|
// to event log.
|
|
StraceEventWhitelist []string
|
|
}
|
|
|
|
// Logging provides functions related to logging.
|
|
type Logging struct{}
|
|
|
|
// Change will change the log level and strace arguments. Although
|
|
// this functions signature requires an error it never acctually
|
|
// return san error. It's required by the URPC interface.
|
|
// Additionally, it may look odd that this is the only method
|
|
// attached to an empty struct but this is also part of how
|
|
// URPC dispatches.
|
|
func (l *Logging) Change(args *LoggingArgs, code *int) error {
|
|
if args.SetLevel {
|
|
// Logging uses an atomic for the level so this is thread safe.
|
|
log.SetLevel(args.Level)
|
|
}
|
|
|
|
if args.SetLogPackets {
|
|
if args.LogPackets {
|
|
atomic.StoreUint32(&sniffer.LogPackets, 1)
|
|
} else {
|
|
atomic.StoreUint32(&sniffer.LogPackets, 0)
|
|
}
|
|
log.Infof("LogPackets set to: %v", atomic.LoadUint32(&sniffer.LogPackets))
|
|
}
|
|
|
|
if args.SetStrace {
|
|
if err := l.configureStrace(args); err != nil {
|
|
return fmt.Errorf("error configuring strace: %v", err)
|
|
}
|
|
}
|
|
|
|
if args.SetEventStrace {
|
|
if err := l.configureEventStrace(args); err != nil {
|
|
return fmt.Errorf("error configuring event strace: %v", err)
|
|
}
|
|
}
|
|
|
|
return nil
|
|
}
|
|
|
|
func (l *Logging) configureStrace(args *LoggingArgs) error {
|
|
if args.EnableStrace {
|
|
// Install the whitelist specified.
|
|
if len(args.StraceWhitelist) > 0 {
|
|
if err := strace.Enable(args.StraceWhitelist, strace.SinkTypeLog); err != nil {
|
|
return err
|
|
}
|
|
} else {
|
|
// For convenience, if strace is enabled but whitelist
|
|
// is empty, enable everything to log.
|
|
strace.EnableAll(strace.SinkTypeLog)
|
|
}
|
|
} else {
|
|
// Uninstall all strace functions.
|
|
strace.Disable(strace.SinkTypeLog)
|
|
}
|
|
return nil
|
|
}
|
|
|
|
func (l *Logging) configureEventStrace(args *LoggingArgs) error {
|
|
if len(args.StraceEventWhitelist) > 0 {
|
|
if err := strace.Enable(args.StraceEventWhitelist, strace.SinkTypeEvent); err != nil {
|
|
return err
|
|
}
|
|
} else {
|
|
strace.Disable(strace.SinkTypeEvent)
|
|
}
|
|
return nil
|
|
}
|