提交 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 (
"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
// as `runc init` executes entrypoint. Thus, some internal states in form of
// environment variable must be staged and then recovered after re-exec. This
......@@ -13,54 +28,12 @@ import (
func StartBootstrap(initPipe *os.File, logPipe *os.File, logLevel string, fifoFd int, agentPipe *os.File, detached string) (err error) {
logrus.Debug("bootstrapping libenclave ...")
if err = stageFd("_LIBENCLAVE_INITPIPE", initPipe); err != nil {
return err
}
defer func() {
if err != nil {
unstageFd("_LIBENCLAVE_INITPIPE")
}
}()
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")
}
}()
enclaveEnv.initPipe = initPipe
enclaveEnv.logPipe = logPipe
enclaveEnv.logLevel = logLevel
enclaveEnv.fifoFd = fifoFd
enclaveEnv.agentPipe = agentPipe
enclaveEnv.detached = detached
os.Setenv("_LIBENCLAVE_DETACHED", detached)
return nil
}
......@@ -23,43 +23,16 @@ const signalBufferSize = 2048
var enclaveRuntime *runtime.EnclaveRuntimeWrapper
func StartInitialization() (exitCode int32, err error) {
logLevel := os.Getenv("_LIBENCLAVE_LOGLEVEL")
env := GetEnclaveRunetimeEnv()
// Make the unused environment variables invisible to enclave runtime.
os.Unsetenv("_LIBENCLAVE_LOGPIPE")
os.Unsetenv("_LIBENCLAVE_LOGLEVEL")
logLevel := env.logLevel
// Determine which type of runelet is initializing.
var fifoFd = -1
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
}
}
fifoFd := env.fifoFd
// Retrieve the init pipe fd to accomplish the enclave configuration
// handshake as soon as possible with parent rune.
envInitPipe := os.Getenv("_LIBENCLAVE_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")
initPipe := env.initPipe
defer func() {
if err != nil {
initPipe.Close()
......@@ -98,17 +71,14 @@ func StartInitialization() (exitCode int32, err error) {
}
// If runelet run as detach mode, close logrus before initpipe closed.
envDetach := os.Getenv("_LIBENCLAVE_DETACHED")
detach, err := strconv.Atoi(envDetach)
detach, err := strconv.Atoi(env.detached)
if detach != 0 {
logrus.SetOutput(ioutil.Discard)
}
os.Unsetenv("_LIBENCLAVE_DETACHED")
// 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.
initPipe.Close()
os.Unsetenv("_LIBENCLAVE_INITPIPE")
// Take care the execution sequence among components. Closing exec fifo
// made by finalizeInitialization() allows the execution of `rune start`
......@@ -116,22 +86,8 @@ func StartInitialization() (exitCode int32, err error) {
// and entrypoint, implying `rune exec` may preempt them too.
// Launch agent service for child runelet.
envAgentPipe := os.Getenv("_LIBENCLAVE_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")
agentPipe := env.agentPipe
defer agentPipe.Close()
os.Unsetenv("_LIBENCLAVE_AGENTPIPE")
notifySignal := make(chan os.Signal, signalBufferSize)
......@@ -152,7 +108,6 @@ func StartInitialization() (exitCode int32, err error) {
if err = finalizeInitialization(fifoFd); err != nil {
return 1, err
}
os.Unsetenv("_LIBENCLAVE_FIFOFD")
// Capture all signals and then forward to enclave runtime.
signal.Notify(notifySignal)
......
......@@ -7,11 +7,7 @@ import (
"github.com/golang/protobuf/proto"
"github.com/opencontainers/runc/libcontainer/stacktrace"
pb "github.com/opencontainers/runc/libenclave/proto"
"golang.org/x/sys/unix"
"io"
"os"
"strconv"
"syscall"
"time"
"unsafe"
)
......@@ -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)
}
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 {
var sz uint32
data := make([]byte, unsafe.Sizeof(sz))
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册