github.com/MerlinKodo/gvisor@v0.0.0-20231110090155-957f62ecf90e/pkg/sentry/control/logging.go (about)

     1  // Copyright 2019 The gVisor Authors.
     2  //
     3  // Licensed under the Apache License, Version 2.0 (the "License");
     4  // you may not use this file except in compliance with the License.
     5  // You may obtain a copy of the License at
     6  //
     7  //     http://www.apache.org/licenses/LICENSE-2.0
     8  //
     9  // Unless required by applicable law or agreed to in writing, software
    10  // distributed under the License is distributed on an "AS IS" BASIS,
    11  // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    12  // See the License for the specific language governing permissions and
    13  // limitations under the License.
    14  
    15  package control
    16  
    17  import (
    18  	"fmt"
    19  
    20  	"github.com/MerlinKodo/gvisor/pkg/log"
    21  	"github.com/MerlinKodo/gvisor/pkg/sentry/strace"
    22  	"github.com/MerlinKodo/gvisor/pkg/tcpip/link/sniffer"
    23  )
    24  
    25  // LoggingArgs are the arguments to use for changing the logging
    26  // level and strace list.
    27  type LoggingArgs struct {
    28  	// SetLevel is a flag used to indicate that we should update
    29  	// the logging level. We should be able to change the strace
    30  	// list without affecting the logging level and vice versa.
    31  	SetLevel bool
    32  
    33  	// Level is the log level that will be set if SetLevel is true.
    34  	Level log.Level
    35  
    36  	// SetLogPackets indicates that we should update the log packets flag.
    37  	SetLogPackets bool
    38  
    39  	// LogPackets is the actual value to set for LogPackets.
    40  	// SetLogPackets must be enabled to indicate that we're changing
    41  	// the value.
    42  	LogPackets bool
    43  
    44  	// SetStrace is a flag used to indicate that strace related
    45  	// arguments were passed in.
    46  	SetStrace bool
    47  
    48  	// EnableStrace is a flag from the CLI that specifies whether to
    49  	// enable strace at all. If this flag is false then a completely
    50  	// pristine copy of the syscall table will be swapped in. This
    51  	// approach is used to remain consistent with an empty strace
    52  	// allowlist meaning trace all system calls.
    53  	EnableStrace bool
    54  
    55  	// Strace is the allowlist of syscalls to trace to log. If this
    56  	// and StraceEventAllowlist are empty trace all system calls.
    57  	StraceAllowlist []string
    58  
    59  	// SetEventStrace is a flag used to indicate that event strace
    60  	// related arguments were passed in.
    61  	SetEventStrace bool
    62  
    63  	// StraceEventAllowlist is the allowlist of syscalls to trace
    64  	// to event log.
    65  	StraceEventAllowlist []string
    66  }
    67  
    68  // Logging provides functions related to logging.
    69  type Logging struct{}
    70  
    71  // Change will change the log level and strace arguments. Although
    72  // this functions signature requires an error it never actually
    73  // returns an error. It's required by the URPC interface.
    74  // Additionally, it may look odd that this is the only method
    75  // attached to an empty struct but this is also part of how
    76  // URPC dispatches.
    77  func (l *Logging) Change(args *LoggingArgs, code *int) error {
    78  	if args.SetLevel {
    79  		// Logging uses an atomic for the level so this is thread safe.
    80  		log.SetLevel(args.Level)
    81  	}
    82  
    83  	if args.SetLogPackets {
    84  		if args.LogPackets {
    85  			sniffer.LogPackets.Store(1)
    86  		} else {
    87  			sniffer.LogPackets.Store(0)
    88  		}
    89  		log.Infof("LogPackets set to: %v", sniffer.LogPackets.Load())
    90  	}
    91  
    92  	if args.SetStrace {
    93  		if err := l.configureStrace(args); err != nil {
    94  			return fmt.Errorf("error configuring strace: %v", err)
    95  		}
    96  	}
    97  
    98  	if args.SetEventStrace {
    99  		if err := l.configureEventStrace(args); err != nil {
   100  			return fmt.Errorf("error configuring event strace: %v", err)
   101  		}
   102  	}
   103  
   104  	return nil
   105  }
   106  
   107  func (l *Logging) configureStrace(args *LoggingArgs) error {
   108  	if args.EnableStrace {
   109  		// Install the allowlist specified.
   110  		if len(args.StraceAllowlist) > 0 {
   111  			if err := strace.Enable(args.StraceAllowlist, strace.SinkTypeLog); err != nil {
   112  				return err
   113  			}
   114  		} else {
   115  			// For convenience, if strace is enabled but allowlist
   116  			// is empty, enable everything to log.
   117  			strace.EnableAll(strace.SinkTypeLog)
   118  		}
   119  	} else {
   120  		// Uninstall all strace functions.
   121  		strace.Disable(strace.SinkTypeLog)
   122  	}
   123  	return nil
   124  }
   125  
   126  func (l *Logging) configureEventStrace(args *LoggingArgs) error {
   127  	if len(args.StraceEventAllowlist) > 0 {
   128  		if err := strace.Enable(args.StraceEventAllowlist, strace.SinkTypeEvent); err != nil {
   129  			return err
   130  		}
   131  	} else {
   132  		strace.Disable(strace.SinkTypeEvent)
   133  	}
   134  	return nil
   135  }