Portability fixes for containerd shim
Update go-runc to master with portability fixes. Subreaper only exists on Linux, and only Linux runs the shim in a mount namespace. With these changes the shim compiles on Darwin, which means the whole build compiles without errors now. Signed-off-by: Justin Cormack <justin.cormack@docker.com>
This commit is contained in:
		
							
								
								
									
										95
									
								
								vendor/github.com/opencontainers/runc/libcontainer/utils/cmsg.go
									
									
									
										generated
									
									
										vendored
									
									
								
							
							
						
						
									
										95
									
								
								vendor/github.com/opencontainers/runc/libcontainer/utils/cmsg.go
									
									
									
										generated
									
									
										vendored
									
									
								
							@@ -1,95 +0,0 @@
 | 
			
		||||
// +build linux
 | 
			
		||||
 | 
			
		||||
package utils
 | 
			
		||||
 | 
			
		||||
/*
 | 
			
		||||
 * Copyright 2016, 2017 SUSE LLC
 | 
			
		||||
 *
 | 
			
		||||
 * 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.
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
import (
 | 
			
		||||
	"fmt"
 | 
			
		||||
	"os"
 | 
			
		||||
 | 
			
		||||
	"golang.org/x/sys/unix"
 | 
			
		||||
)
 | 
			
		||||
 | 
			
		||||
// MaxSendfdLen is the maximum length of the name of a file descriptor being
 | 
			
		||||
// sent using SendFd. The name of the file handle returned by RecvFd will never
 | 
			
		||||
// be larger than this value.
 | 
			
		||||
const MaxNameLen = 4096
 | 
			
		||||
 | 
			
		||||
// oobSpace is the size of the oob slice required to store a single FD. Note
 | 
			
		||||
// that unix.UnixRights appears to make the assumption that fd is always int32,
 | 
			
		||||
// so sizeof(fd) = 4.
 | 
			
		||||
var oobSpace = unix.CmsgSpace(4)
 | 
			
		||||
 | 
			
		||||
// RecvFd waits for a file descriptor to be sent over the given AF_UNIX
 | 
			
		||||
// socket. The file name of the remote file descriptor will be recreated
 | 
			
		||||
// locally (it is sent as non-auxiliary data in the same payload).
 | 
			
		||||
func RecvFd(socket *os.File) (*os.File, error) {
 | 
			
		||||
	// For some reason, unix.Recvmsg uses the length rather than the capacity
 | 
			
		||||
	// when passing the msg_controllen and other attributes to recvmsg.  So we
 | 
			
		||||
	// have to actually set the length.
 | 
			
		||||
	name := make([]byte, MaxNameLen)
 | 
			
		||||
	oob := make([]byte, oobSpace)
 | 
			
		||||
 | 
			
		||||
	sockfd := socket.Fd()
 | 
			
		||||
	n, oobn, _, _, err := unix.Recvmsg(int(sockfd), name, oob, 0)
 | 
			
		||||
	if err != nil {
 | 
			
		||||
		return nil, err
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	if n >= MaxNameLen || oobn != oobSpace {
 | 
			
		||||
		return nil, fmt.Errorf("recvfd: incorrect number of bytes read (n=%d oobn=%d)", n, oobn)
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	// Truncate.
 | 
			
		||||
	name = name[:n]
 | 
			
		||||
	oob = oob[:oobn]
 | 
			
		||||
 | 
			
		||||
	scms, err := unix.ParseSocketControlMessage(oob)
 | 
			
		||||
	if err != nil {
 | 
			
		||||
		return nil, err
 | 
			
		||||
	}
 | 
			
		||||
	if len(scms) != 1 {
 | 
			
		||||
		return nil, fmt.Errorf("recvfd: number of SCMs is not 1: %d", len(scms))
 | 
			
		||||
	}
 | 
			
		||||
	scm := scms[0]
 | 
			
		||||
 | 
			
		||||
	fds, err := unix.ParseUnixRights(&scm)
 | 
			
		||||
	if err != nil {
 | 
			
		||||
		return nil, err
 | 
			
		||||
	}
 | 
			
		||||
	if len(fds) != 1 {
 | 
			
		||||
		return nil, fmt.Errorf("recvfd: number of fds is not 1: %d", len(fds))
 | 
			
		||||
	}
 | 
			
		||||
	fd := uintptr(fds[0])
 | 
			
		||||
 | 
			
		||||
	return os.NewFile(fd, string(name)), nil
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// SendFd sends a file descriptor over the given AF_UNIX socket. In
 | 
			
		||||
// addition, the file.Name() of the given file will also be sent as
 | 
			
		||||
// non-auxiliary data in the same payload (allowing to send contextual
 | 
			
		||||
// information for a file descriptor).
 | 
			
		||||
func SendFd(socket, file *os.File) error {
 | 
			
		||||
	name := []byte(file.Name())
 | 
			
		||||
	if len(name) >= MaxNameLen {
 | 
			
		||||
		return fmt.Errorf("sendfd: filename too long: %s", file.Name())
 | 
			
		||||
	}
 | 
			
		||||
	oob := unix.UnixRights(int(file.Fd()))
 | 
			
		||||
 | 
			
		||||
	return unix.Sendmsg(int(socket.Fd()), name, oob, nil, 0)
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										126
									
								
								vendor/github.com/opencontainers/runc/libcontainer/utils/utils.go
									
									
									
										generated
									
									
										vendored
									
									
								
							
							
						
						
									
										126
									
								
								vendor/github.com/opencontainers/runc/libcontainer/utils/utils.go
									
									
									
										generated
									
									
										vendored
									
									
								
							@@ -1,126 +0,0 @@
 | 
			
		||||
package utils
 | 
			
		||||
 | 
			
		||||
import (
 | 
			
		||||
	"crypto/rand"
 | 
			
		||||
	"encoding/hex"
 | 
			
		||||
	"encoding/json"
 | 
			
		||||
	"io"
 | 
			
		||||
	"os"
 | 
			
		||||
	"path/filepath"
 | 
			
		||||
	"strings"
 | 
			
		||||
	"syscall"
 | 
			
		||||
	"unsafe"
 | 
			
		||||
)
 | 
			
		||||
 | 
			
		||||
const (
 | 
			
		||||
	exitSignalOffset = 128
 | 
			
		||||
)
 | 
			
		||||
 | 
			
		||||
// GenerateRandomName returns a new name joined with a prefix.  This size
 | 
			
		||||
// specified is used to truncate the randomly generated value
 | 
			
		||||
func GenerateRandomName(prefix string, size int) (string, error) {
 | 
			
		||||
	id := make([]byte, 32)
 | 
			
		||||
	if _, err := io.ReadFull(rand.Reader, id); err != nil {
 | 
			
		||||
		return "", err
 | 
			
		||||
	}
 | 
			
		||||
	if size > 64 {
 | 
			
		||||
		size = 64
 | 
			
		||||
	}
 | 
			
		||||
	return prefix + hex.EncodeToString(id)[:size], nil
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// ResolveRootfs ensures that the current working directory is
 | 
			
		||||
// not a symlink and returns the absolute path to the rootfs
 | 
			
		||||
func ResolveRootfs(uncleanRootfs string) (string, error) {
 | 
			
		||||
	rootfs, err := filepath.Abs(uncleanRootfs)
 | 
			
		||||
	if err != nil {
 | 
			
		||||
		return "", err
 | 
			
		||||
	}
 | 
			
		||||
	return filepath.EvalSymlinks(rootfs)
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// ExitStatus returns the correct exit status for a process based on if it
 | 
			
		||||
// was signaled or exited cleanly
 | 
			
		||||
func ExitStatus(status syscall.WaitStatus) int {
 | 
			
		||||
	if status.Signaled() {
 | 
			
		||||
		return exitSignalOffset + int(status.Signal())
 | 
			
		||||
	}
 | 
			
		||||
	return status.ExitStatus()
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// WriteJSON writes the provided struct v to w using standard json marshaling
 | 
			
		||||
func WriteJSON(w io.Writer, v interface{}) error {
 | 
			
		||||
	data, err := json.Marshal(v)
 | 
			
		||||
	if err != nil {
 | 
			
		||||
		return err
 | 
			
		||||
	}
 | 
			
		||||
	_, err = w.Write(data)
 | 
			
		||||
	return err
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// CleanPath makes a path safe for use with filepath.Join. This is done by not
 | 
			
		||||
// only cleaning the path, but also (if the path is relative) adding a leading
 | 
			
		||||
// '/' and cleaning it (then removing the leading '/'). This ensures that a
 | 
			
		||||
// path resulting from prepending another path will always resolve to lexically
 | 
			
		||||
// be a subdirectory of the prefixed path. This is all done lexically, so paths
 | 
			
		||||
// that include symlinks won't be safe as a result of using CleanPath.
 | 
			
		||||
func CleanPath(path string) string {
 | 
			
		||||
	// Deal with empty strings nicely.
 | 
			
		||||
	if path == "" {
 | 
			
		||||
		return ""
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	// Ensure that all paths are cleaned (especially problematic ones like
 | 
			
		||||
	// "/../../../../../" which can cause lots of issues).
 | 
			
		||||
	path = filepath.Clean(path)
 | 
			
		||||
 | 
			
		||||
	// If the path isn't absolute, we need to do more processing to fix paths
 | 
			
		||||
	// such as "../../../../<etc>/some/path". We also shouldn't convert absolute
 | 
			
		||||
	// paths to relative ones.
 | 
			
		||||
	if !filepath.IsAbs(path) {
 | 
			
		||||
		path = filepath.Clean(string(os.PathSeparator) + path)
 | 
			
		||||
		// This can't fail, as (by definition) all paths are relative to root.
 | 
			
		||||
		path, _ = filepath.Rel(string(os.PathSeparator), path)
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	// Clean the path again for good measure.
 | 
			
		||||
	return filepath.Clean(path)
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// SearchLabels searches a list of key-value pairs for the provided key and
 | 
			
		||||
// returns the corresponding value. The pairs must be separated with '='.
 | 
			
		||||
func SearchLabels(labels []string, query string) string {
 | 
			
		||||
	for _, l := range labels {
 | 
			
		||||
		parts := strings.SplitN(l, "=", 2)
 | 
			
		||||
		if len(parts) < 2 {
 | 
			
		||||
			continue
 | 
			
		||||
		}
 | 
			
		||||
		if parts[0] == query {
 | 
			
		||||
			return parts[1]
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
	return ""
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// Annotations returns the bundle path and user defined annotations from the
 | 
			
		||||
// libcontainer state.  We need to remove the bundle because that is a label
 | 
			
		||||
// added by libcontainer.
 | 
			
		||||
func Annotations(labels []string) (bundle string, userAnnotations map[string]string) {
 | 
			
		||||
	userAnnotations = make(map[string]string)
 | 
			
		||||
	for _, l := range labels {
 | 
			
		||||
		parts := strings.SplitN(l, "=", 2)
 | 
			
		||||
		if len(parts) < 2 {
 | 
			
		||||
			continue
 | 
			
		||||
		}
 | 
			
		||||
		if parts[0] == "bundle" {
 | 
			
		||||
			bundle = parts[1]
 | 
			
		||||
		} else {
 | 
			
		||||
			userAnnotations[parts[0]] = parts[1]
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
	return
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func GetIntSize() int {
 | 
			
		||||
	return int(unsafe.Sizeof(1))
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										43
									
								
								vendor/github.com/opencontainers/runc/libcontainer/utils/utils_unix.go
									
									
									
										generated
									
									
										vendored
									
									
								
							
							
						
						
									
										43
									
								
								vendor/github.com/opencontainers/runc/libcontainer/utils/utils_unix.go
									
									
									
										generated
									
									
										vendored
									
									
								
							@@ -1,43 +0,0 @@
 | 
			
		||||
// +build !windows
 | 
			
		||||
 | 
			
		||||
package utils
 | 
			
		||||
 | 
			
		||||
import (
 | 
			
		||||
	"io/ioutil"
 | 
			
		||||
	"os"
 | 
			
		||||
	"strconv"
 | 
			
		||||
	"syscall"
 | 
			
		||||
)
 | 
			
		||||
 | 
			
		||||
func CloseExecFrom(minFd int) error {
 | 
			
		||||
	fdList, err := ioutil.ReadDir("/proc/self/fd")
 | 
			
		||||
	if err != nil {
 | 
			
		||||
		return err
 | 
			
		||||
	}
 | 
			
		||||
	for _, fi := range fdList {
 | 
			
		||||
		fd, err := strconv.Atoi(fi.Name())
 | 
			
		||||
		if err != nil {
 | 
			
		||||
			// ignore non-numeric file names
 | 
			
		||||
			continue
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		if fd < minFd {
 | 
			
		||||
			// ignore descriptors lower than our specified minimum
 | 
			
		||||
			continue
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		// intentionally ignore errors from syscall.CloseOnExec
 | 
			
		||||
		syscall.CloseOnExec(fd)
 | 
			
		||||
		// the cases where this might fail are basically file descriptors that have already been closed (including and especially the one that was created when ioutil.ReadDir did the "opendir" syscall)
 | 
			
		||||
	}
 | 
			
		||||
	return nil
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// NewSockPair returns a new unix socket pair
 | 
			
		||||
func NewSockPair(name string) (parent *os.File, child *os.File, err error) {
 | 
			
		||||
	fds, err := syscall.Socketpair(syscall.AF_LOCAL, syscall.SOCK_STREAM|syscall.SOCK_CLOEXEC, 0)
 | 
			
		||||
	if err != nil {
 | 
			
		||||
		return nil, nil, err
 | 
			
		||||
	}
 | 
			
		||||
	return os.NewFile(uintptr(fds[1]), name+"-p"), os.NewFile(uintptr(fds[0]), name+"-c"), nil
 | 
			
		||||
}
 | 
			
		||||
		Reference in New Issue
	
	Block a user