提交 4747d9d5 编写于 作者: T Tianjia Zhang 提交者: jia zhang

rune/libenclave: Optimize the way of passing parameters

Because there is no re-exec operation, there is no need to use
environment variables to pass parameters between bootstrap and
runelet, use global variables instead of environment variables.
Signed-off-by: NTianjia Zhang <tianjia.zhang@linux.alibaba.com>
上级 1adab6cf
...@@ -5,6 +5,21 @@ import ( ...@@ -5,6 +5,21 @@ import (
"os" "os"
) )
type enclaveRuntimeEnv struct {
initPipe *os.File
logPipe *os.File
logLevel string
fifoFd int
agentPipe *os.File
detached string
}
var enclaveEnv enclaveRuntimeEnv
func GetEnclaveRunetimeEnv() *enclaveRuntimeEnv {
return &enclaveEnv
}
// `rune init` needs to execute self (/proc/self/exe) in container environment // `rune init` needs to execute self (/proc/self/exe) in container environment
// as `runc init` executes entrypoint. Thus, some internal states in form of // as `runc init` executes entrypoint. Thus, some internal states in form of
// environment variable must be staged and then recovered after re-exec. This // environment variable must be staged and then recovered after re-exec. This
...@@ -13,54 +28,12 @@ import ( ...@@ -13,54 +28,12 @@ import (
func StartBootstrap(initPipe *os.File, logPipe *os.File, logLevel string, fifoFd int, agentPipe *os.File, detached string) (err error) { func StartBootstrap(initPipe *os.File, logPipe *os.File, logLevel string, fifoFd int, agentPipe *os.File, detached string) (err error) {
logrus.Debug("bootstrapping libenclave ...") logrus.Debug("bootstrapping libenclave ...")
if err = stageFd("_LIBENCLAVE_INITPIPE", initPipe); err != nil { enclaveEnv.initPipe = initPipe
return err enclaveEnv.logPipe = logPipe
} enclaveEnv.logLevel = logLevel
defer func() { enclaveEnv.fifoFd = fifoFd
if err != nil { enclaveEnv.agentPipe = agentPipe
unstageFd("_LIBENCLAVE_INITPIPE") enclaveEnv.detached = detached
}
}()
if fifoFd != -1 {
if err = stageFd("_LIBENCLAVE_FIFOFD", fifoFd); err != nil {
return err
}
defer func() {
if err != nil {
unstageFd("_LIBENCLAVE_FIFOFD")
}
}()
}
if err = stageFd("_LIBENCLAVE_LOGPIPE", logPipe); err != nil {
return err
}
defer func() {
if err != nil {
unstageFd("_LIBENCLAVE_LOGPIPE")
}
}()
if err = os.Setenv("_LIBENCLAVE_LOGLEVEL", logLevel); err != nil {
return err
}
defer func() {
if err != nil {
os.Unsetenv("_LIBENCLAVE_LOGLEVEL")
}
}()
if err = stageFd("_LIBENCLAVE_AGENTPIPE", agentPipe); err != nil {
return err
}
defer func() {
if err != nil {
unstageFd("_LIBENCLAVE_AGENTPIPE")
}
}()
os.Setenv("_LIBENCLAVE_DETACHED", detached)
return nil return nil
} }
...@@ -23,43 +23,16 @@ const signalBufferSize = 2048 ...@@ -23,43 +23,16 @@ const signalBufferSize = 2048
var enclaveRuntime *runtime.EnclaveRuntimeWrapper var enclaveRuntime *runtime.EnclaveRuntimeWrapper
func StartInitialization() (exitCode int32, err error) { func StartInitialization() (exitCode int32, err error) {
logLevel := os.Getenv("_LIBENCLAVE_LOGLEVEL") env := GetEnclaveRunetimeEnv()
// Make the unused environment variables invisible to enclave runtime. logLevel := env.logLevel
os.Unsetenv("_LIBENCLAVE_LOGPIPE")
os.Unsetenv("_LIBENCLAVE_LOGLEVEL")
// Determine which type of runelet is initializing. // Determine which type of runelet is initializing.
var fifoFd = -1 fifoFd := env.fifoFd
envFifoFd := os.Getenv("_LIBENCLAVE_FIFOFD")
if envFifoFd != "" {
defer func() {
if err != nil {
unstageFd("_LIBENCLAVE_FIFOFD")
}
}()
fifoFd, err = strconv.Atoi(envFifoFd)
if err != nil {
return 1, err
}
}
// Retrieve the init pipe fd to accomplish the enclave configuration // Retrieve the init pipe fd to accomplish the enclave configuration
// handshake as soon as possible with parent rune. // handshake as soon as possible with parent rune.
envInitPipe := os.Getenv("_LIBENCLAVE_INITPIPE") initPipe := env.initPipe
if envInitPipe == "" {
return 1, fmt.Errorf("unable to get _LIBENCLAVE_INITPIPE")
}
defer func() {
if err != nil {
unstageFd("_LIBENCLAVE_INITPIPE")
}
}()
pipeFd, err := strconv.Atoi(envInitPipe)
if err != nil {
return 1, err
}
initPipe := os.NewFile(uintptr(pipeFd), "init-pipe")
defer func() { defer func() {
if err != nil { if err != nil {
initPipe.Close() initPipe.Close()
...@@ -98,17 +71,14 @@ func StartInitialization() (exitCode int32, err error) { ...@@ -98,17 +71,14 @@ func StartInitialization() (exitCode int32, err error) {
} }
// If runelet run as detach mode, close logrus before initpipe closed. // If runelet run as detach mode, close logrus before initpipe closed.
envDetach := os.Getenv("_LIBENCLAVE_DETACHED") detach, err := strconv.Atoi(env.detached)
detach, err := strconv.Atoi(envDetach)
if detach != 0 { if detach != 0 {
logrus.SetOutput(ioutil.Discard) logrus.SetOutput(ioutil.Discard)
} }
os.Unsetenv("_LIBENCLAVE_DETACHED")
// Close the init pipe to signal that we have completed our init. // Close the init pipe to signal that we have completed our init.
// So `rune create` or the upper half part of `rune run` can return. // So `rune create` or the upper half part of `rune run` can return.
initPipe.Close() initPipe.Close()
os.Unsetenv("_LIBENCLAVE_INITPIPE")
// Take care the execution sequence among components. Closing exec fifo // Take care the execution sequence among components. Closing exec fifo
// made by finalizeInitialization() allows the execution of `rune start` // made by finalizeInitialization() allows the execution of `rune start`
...@@ -116,22 +86,8 @@ func StartInitialization() (exitCode int32, err error) { ...@@ -116,22 +86,8 @@ func StartInitialization() (exitCode int32, err error) {
// and entrypoint, implying `rune exec` may preempt them too. // and entrypoint, implying `rune exec` may preempt them too.
// Launch agent service for child runelet. // Launch agent service for child runelet.
envAgentPipe := os.Getenv("_LIBENCLAVE_AGENTPIPE") agentPipe := env.agentPipe
if envAgentPipe == "" {
return 1, fmt.Errorf("unable to get _LIBENCLAVE_AGENTPIPE")
}
defer func() {
if err != nil {
unstageFd("_LIBENCLAVE_AGENTPIPE")
}
}()
agentPipeFd, err := strconv.Atoi(envAgentPipe)
if err != nil {
return 1, err
}
agentPipe := os.NewFile(uintptr(agentPipeFd), "agent-pipe")
defer agentPipe.Close() defer agentPipe.Close()
os.Unsetenv("_LIBENCLAVE_AGENTPIPE")
notifySignal := make(chan os.Signal, signalBufferSize) notifySignal := make(chan os.Signal, signalBufferSize)
...@@ -152,7 +108,6 @@ func StartInitialization() (exitCode int32, err error) { ...@@ -152,7 +108,6 @@ func StartInitialization() (exitCode int32, err error) {
if err = finalizeInitialization(fifoFd); err != nil { if err = finalizeInitialization(fifoFd); err != nil {
return 1, err return 1, err
} }
os.Unsetenv("_LIBENCLAVE_FIFOFD")
// Capture all signals and then forward to enclave runtime. // Capture all signals and then forward to enclave runtime.
signal.Notify(notifySignal) signal.Notify(notifySignal)
......
...@@ -7,11 +7,7 @@ import ( ...@@ -7,11 +7,7 @@ import (
"github.com/golang/protobuf/proto" "github.com/golang/protobuf/proto"
"github.com/opencontainers/runc/libcontainer/stacktrace" "github.com/opencontainers/runc/libcontainer/stacktrace"
pb "github.com/opencontainers/runc/libenclave/proto" pb "github.com/opencontainers/runc/libenclave/proto"
"golang.org/x/sys/unix"
"io" "io"
"os"
"strconv"
"syscall"
"time" "time"
"unsafe" "unsafe"
) )
...@@ -36,48 +32,6 @@ func (e *genericError) Error() string { ...@@ -36,48 +32,6 @@ func (e *genericError) Error() string {
return fmt.Sprintf("%s:%d: %s caused %q", frame.File, frame.Line, e.Cause, e.Message) return fmt.Sprintf("%s:%d: %s caused %q", frame.File, frame.Line, e.Cause, e.Message)
} }
func stageFd(env string, f interface{}) (err error) {
var fd int
switch f := f.(type) {
case *os.File:
fd = int(f.Fd())
case int:
fd = f
default:
return fmt.Errorf("unsupported type of environment variable %s", env)
}
flags, err := unix.FcntlInt(uintptr(fd), syscall.F_GETFD, 0)
if err != nil {
return err
}
if flags&syscall.FD_CLOEXEC == syscall.FD_CLOEXEC {
flags &^= syscall.FD_CLOEXEC
_, err := unix.FcntlInt(uintptr(fd), syscall.F_SETFD, flags)
if err != nil {
return err
}
}
err = os.Setenv(env, strconv.Itoa(fd))
if err != nil {
return err
}
return nil
}
func unstageFd(env string) {
f := os.Getenv(env)
os.Unsetenv(env)
if f != "" {
fd, err := strconv.Atoi(f)
if err == nil {
unix.Close(fd)
}
}
}
func protoBufRead(conn io.Reader, unmarshaled interface{}) error { func protoBufRead(conn io.Reader, unmarshaled interface{}) error {
var sz uint32 var sz uint32
data := make([]byte, unsafe.Sizeof(sz)) data := make([]byte, unsafe.Sizeof(sz))
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册