From 789a73db22b5618486a06cdf6e8616bf55d9ae9f Mon Sep 17 00:00:00 2001 From: Kir Kolyshkin Date: Thu, 9 Dec 2021 13:01:03 -0800 Subject: [PATCH] init.go: move logger setup to StartInitialization Currently, logrus is used from the Go part of runc init, mostly for a few debug messages (see setns_init_linux.go and standard_init_linux.go), and a single warning (see rootfs_linux.go). This means logrus is part of init implementation, and thus, its setup belongs to StartInitialization(). Move the code there. As a nice side effect, now we don't have to convert _LIBCONTAINER_LOGPIPE twice. Note that since this initialization is now also called from libct/int tests, which do not set _LIBCONTAINER_LOGLEVEL, let's make _LIBCONTAINER_LOGLEVEL optional. Signed-off-by: Kir Kolyshkin --- init.go | 17 ----------------- libcontainer/container_linux.go | 7 ++++--- libcontainer/init_linux.go | 32 ++++++++++++++++++++++---------- 3 files changed, 26 insertions(+), 30 deletions(-) diff --git a/init.go b/init.go index 2f44ce8a5..79176e2f1 100644 --- a/init.go +++ b/init.go @@ -3,11 +3,9 @@ package main import ( "os" "runtime" - "strconv" "github.com/opencontainers/runc/libcontainer" _ "github.com/opencontainers/runc/libcontainer/nsenter" - "github.com/sirupsen/logrus" ) func init() { @@ -17,21 +15,6 @@ func init() { runtime.GOMAXPROCS(1) runtime.LockOSThread() - level, err := strconv.Atoi(os.Getenv("_LIBCONTAINER_LOGLEVEL")) - if err != nil { - panic(err) - } - - logPipeFd, err := strconv.Atoi(os.Getenv("_LIBCONTAINER_LOGPIPE")) - if err != nil { - panic(err) - } - - logrus.SetLevel(logrus.Level(level)) - logrus.SetOutput(os.NewFile(uintptr(logPipeFd), "logpipe")) - logrus.SetFormatter(new(logrus.JSONFormatter)) - logrus.Debug("child process in init()") - if err := libcontainer.StartInitialization(); err != nil { // as the error is sent back to the parent there is no need to log // or write it to stderr because the parent process will handle this diff --git a/libcontainer/container_linux.go b/libcontainer/container_linux.go index 2f0a6c641..1756c384c 100644 --- a/libcontainer/container_linux.go +++ b/libcontainer/container_linux.go @@ -501,9 +501,10 @@ func (c *Container) commandTemplate(p *Process, childInitPipe *os.File, childLog cmd.ExtraFiles = append(cmd.ExtraFiles, childLogPipe) cmd.Env = append(cmd.Env, - "_LIBCONTAINER_LOGPIPE="+strconv.Itoa(stdioFdCount+len(cmd.ExtraFiles)-1), - "_LIBCONTAINER_LOGLEVEL="+p.LogLevel, - ) + "_LIBCONTAINER_LOGPIPE="+strconv.Itoa(stdioFdCount+len(cmd.ExtraFiles)-1)) + if p.LogLevel != "" { + cmd.Env = append(cmd.Env, "_LIBCONTAINER_LOGLEVEL="+p.LogLevel) + } // NOTE: when running a container with no PID namespace and the parent process spawning the container is // PID1 the pdeathsig is being delivered to the container's init process by the kernel for some reason diff --git a/libcontainer/init_linux.go b/libcontainer/init_linux.go index 42cae1ccb..9d187c930 100644 --- a/libcontainer/init_linux.go +++ b/libcontainer/init_linux.go @@ -92,9 +92,7 @@ func StartInitialization() (retErr error) { envInitPipe := os.Getenv("_LIBCONTAINER_INITPIPE") pipefd, err := strconv.Atoi(envInitPipe) if err != nil { - err = fmt.Errorf("unable to convert _LIBCONTAINER_INITPIPE: %w", err) - logrus.Error(err) - return err + return fmt.Errorf("unable to convert _LIBCONTAINER_INITPIPE: %w", err) } pipe := os.NewFile(uintptr(pipefd), "pipe") defer pipe.Close() @@ -112,6 +110,26 @@ func StartInitialization() (retErr error) { } }() + // Set up logging. This is used rarely, and mostly for init debugging. + + // Passing log level is optional; currently libcontainer/integration does not do it. + if levelStr := os.Getenv("_LIBCONTAINER_LOGLEVEL"); levelStr != "" { + logLevel, err := strconv.Atoi(levelStr) + if err != nil { + return fmt.Errorf("unable to convert _LIBCONTAINER_LOGLEVEL: %w", err) + } + logrus.SetLevel(logrus.Level(logLevel)) + } + + logFD, err := strconv.Atoi(os.Getenv("_LIBCONTAINER_LOGPIPE")) + if err != nil { + return fmt.Errorf("unable to convert _LIBCONTAINER_LOGPIPE: %w", err) + } + + logrus.SetOutput(os.NewFile(uintptr(logFD), "logpipe")) + logrus.SetFormatter(new(logrus.JSONFormatter)) + logrus.Debug("child process in init()") + // Only init processes have FIFOFD. fifofd := -1 envInitType := os.Getenv("_LIBCONTAINER_INITTYPE") @@ -133,12 +151,6 @@ func StartInitialization() (retErr error) { defer consoleSocket.Close() } - logPipeFdStr := os.Getenv("_LIBCONTAINER_LOGPIPE") - logPipeFd, err := strconv.Atoi(logPipeFdStr) - if err != nil { - return fmt.Errorf("unable to convert _LIBCONTAINER_LOGPIPE: %w", err) - } - // Get mount files (O_PATH). mountSrcFds, err := parseFdsFromEnv("_LIBCONTAINER_MOUNT_FDS") if err != nil { @@ -166,7 +178,7 @@ func StartInitialization() (retErr error) { }() // If init succeeds, it will not return, hence none of the defers will be called. - return containerInit(it, pipe, consoleSocket, fifofd, logPipeFd, mountFds{sourceFds: mountSrcFds, idmapFds: idmapFds}) + return containerInit(it, pipe, consoleSocket, fifofd, logFD, mountFds{sourceFds: mountSrcFds, idmapFds: idmapFds}) } func containerInit(t initType, pipe *os.File, consoleSocket *os.File, fifoFd, logFd int, mountFds mountFds) error {