Revendor Microsoft/hcsshim and go-winio
Signed-off-by: John Howard <john.howard@microsoft.com>
This commit is contained in:
		| @@ -32,8 +32,8 @@ github.com/opencontainers/image-spec v1.0.1 | ||||
| golang.org/x/sync 450f422ab23cf9881c94e2db30cac0eb1b7cf80c | ||||
| github.com/BurntSushi/toml a368813c5e648fee92e5f6c30e3944ff9d5e8895 | ||||
| github.com/grpc-ecosystem/go-grpc-prometheus 6b7015e65d366bf3f19b2b2a000a831940f0f7e0 | ||||
| github.com/Microsoft/go-winio v0.4.7 | ||||
| github.com/Microsoft/hcsshim v0.6.11 | ||||
| github.com/Microsoft/go-winio v0.4.10 | ||||
| github.com/Microsoft/hcsshim v0.6.14 | ||||
| github.com/boltdb/bolt e9cf4fae01b5a8ff89d0ec6b32f0d9c9f79aefdd | ||||
| google.golang.org/genproto d80a6e20e776b0b17a324d0ba1ab50a39c8e8944 | ||||
| golang.org/x/text 19e51611da83d6be54ddafce4a4af510cb3e9ea4 | ||||
|   | ||||
							
								
								
									
										3
									
								
								vendor/github.com/Microsoft/go-winio/fileinfo.go
									
									
									
										generated
									
									
										vendored
									
									
								
							
							
						
						
									
										3
									
								
								vendor/github.com/Microsoft/go-winio/fileinfo.go
									
									
									
										generated
									
									
										vendored
									
									
								
							| @@ -20,7 +20,8 @@ const ( | ||||
| // FileBasicInfo contains file access time and file attributes information. | ||||
| type FileBasicInfo struct { | ||||
| 	CreationTime, LastAccessTime, LastWriteTime, ChangeTime syscall.Filetime | ||||
| 	FileAttributes                                          uintptr // includes padding | ||||
| 	FileAttributes                                          uint32 | ||||
| 	pad                                                     uint32 // padding | ||||
| } | ||||
|  | ||||
| // GetFileBasicInfo retrieves times and attributes for a file. | ||||
|   | ||||
							
								
								
									
										57
									
								
								vendor/github.com/Microsoft/go-winio/pipe.go
									
									
									
										generated
									
									
										vendored
									
									
								
							
							
						
						
									
										57
									
								
								vendor/github.com/Microsoft/go-winio/pipe.go
									
									
									
										generated
									
									
										vendored
									
									
								
							| @@ -15,7 +15,6 @@ import ( | ||||
| //sys connectNamedPipe(pipe syscall.Handle, o *syscall.Overlapped) (err error) = ConnectNamedPipe | ||||
| //sys createNamedPipe(name string, flags uint32, pipeMode uint32, maxInstances uint32, outSize uint32, inSize uint32, defaultTimeout uint32, sa *syscall.SecurityAttributes) (handle syscall.Handle, err error)  [failretval==syscall.InvalidHandle] = CreateNamedPipeW | ||||
| //sys createFile(name string, access uint32, mode uint32, sa *syscall.SecurityAttributes, createmode uint32, attrs uint32, templatefile syscall.Handle) (handle syscall.Handle, err error) [failretval==syscall.InvalidHandle] = CreateFileW | ||||
| //sys waitNamedPipe(name string, timeout uint32) (err error) = WaitNamedPipeW | ||||
| //sys getNamedPipeInfo(pipe syscall.Handle, flags *uint32, outSize *uint32, inSize *uint32, maxInstances *uint32) (err error) = GetNamedPipeInfo | ||||
| //sys getNamedPipeHandleState(pipe syscall.Handle, state *uint32, curInstances *uint32, maxCollectionCount *uint32, collectDataTimeout *uint32, userName *uint16, maxUserNameSize uint32) (err error) = GetNamedPipeHandleStateW | ||||
| //sys localAlloc(uFlags uint32, length uint32) (ptr uintptr) = LocalAlloc | ||||
| @@ -121,6 +120,11 @@ func (f *win32MessageBytePipe) Read(b []byte) (int, error) { | ||||
| 		// zero-byte message, ensure that all future Read() calls | ||||
| 		// also return EOF. | ||||
| 		f.readEOF = true | ||||
| 	} else if err == syscall.ERROR_MORE_DATA { | ||||
| 		// ERROR_MORE_DATA indicates that the pipe's read mode is message mode | ||||
| 		// and the message still has more bytes. Treat this as a success, since | ||||
| 		// this package presents all named pipes as byte streams. | ||||
| 		err = nil | ||||
| 	} | ||||
| 	return n, err | ||||
| } | ||||
| @@ -134,12 +138,14 @@ func (s pipeAddress) String() string { | ||||
| } | ||||
|  | ||||
| // DialPipe connects to a named pipe by path, timing out if the connection | ||||
| // takes longer than the specified duration. If timeout is nil, then the timeout | ||||
| // is the default timeout established by the pipe server. | ||||
| // takes longer than the specified duration. If timeout is nil, then we use | ||||
| // a default timeout of 5 seconds.  (We do not use WaitNamedPipe.) | ||||
| func DialPipe(path string, timeout *time.Duration) (net.Conn, error) { | ||||
| 	var absTimeout time.Time | ||||
| 	if timeout != nil { | ||||
| 		absTimeout = time.Now().Add(*timeout) | ||||
| 	} else { | ||||
| 		absTimeout = time.Now().Add(time.Second * 2) | ||||
| 	} | ||||
| 	var err error | ||||
| 	var h syscall.Handle | ||||
| @@ -148,22 +154,13 @@ func DialPipe(path string, timeout *time.Duration) (net.Conn, error) { | ||||
| 		if err != cERROR_PIPE_BUSY { | ||||
| 			break | ||||
| 		} | ||||
| 		now := time.Now() | ||||
| 		var ms uint32 | ||||
| 		if absTimeout.IsZero() { | ||||
| 			ms = cNMPWAIT_USE_DEFAULT_WAIT | ||||
| 		} else if now.After(absTimeout) { | ||||
| 			ms = cNMPWAIT_NOWAIT | ||||
| 		} else { | ||||
| 			ms = uint32(absTimeout.Sub(now).Nanoseconds() / 1000 / 1000) | ||||
| 		} | ||||
| 		err = waitNamedPipe(path, ms) | ||||
| 		if err != nil { | ||||
| 			if err == cERROR_SEM_TIMEOUT { | ||||
| 				return nil, ErrTimeout | ||||
| 			} | ||||
| 			break | ||||
| 		if time.Now().After(absTimeout) { | ||||
| 			return nil, ErrTimeout | ||||
| 		} | ||||
|  | ||||
| 		// Wait 10 msec and try again. This is a rather simplistic | ||||
| 		// view, as we always try each 10 milliseconds. | ||||
| 		time.Sleep(time.Millisecond * 10) | ||||
| 	} | ||||
| 	if err != nil { | ||||
| 		return nil, &os.PathError{Op: "open", Path: path, Err: err} | ||||
| @@ -175,16 +172,6 @@ func DialPipe(path string, timeout *time.Duration) (net.Conn, error) { | ||||
| 		return nil, err | ||||
| 	} | ||||
|  | ||||
| 	var state uint32 | ||||
| 	err = getNamedPipeHandleState(h, &state, nil, nil, nil, nil, 0) | ||||
| 	if err != nil { | ||||
| 		return nil, err | ||||
| 	} | ||||
|  | ||||
| 	if state&cPIPE_READMODE_MESSAGE != 0 { | ||||
| 		return nil, &os.PathError{Op: "open", Path: path, Err: errors.New("message readmode pipes not supported")} | ||||
| 	} | ||||
|  | ||||
| 	f, err := makeWin32File(h) | ||||
| 	if err != nil { | ||||
| 		syscall.Close(h) | ||||
| @@ -354,13 +341,23 @@ func ListenPipe(path string, c *PipeConfig) (net.Listener, error) { | ||||
| 	if err != nil { | ||||
| 		return nil, err | ||||
| 	} | ||||
| 	// Immediately open and then close a client handle so that the named pipe is | ||||
| 	// created but not currently accepting connections. | ||||
| 	// Create a client handle and connect it.  This results in the pipe | ||||
| 	// instance always existing, so that clients see ERROR_PIPE_BUSY | ||||
| 	// rather than ERROR_FILE_NOT_FOUND.  This ties the first instance | ||||
| 	// up so that no other instances can be used.  This would have been | ||||
| 	// cleaner if the Win32 API matched CreateFile with ConnectNamedPipe | ||||
| 	// instead of CreateNamedPipe.  (Apparently created named pipes are | ||||
| 	// considered to be in listening state regardless of whether any | ||||
| 	// active calls to ConnectNamedPipe are outstanding.) | ||||
| 	h2, err := createFile(path, 0, 0, nil, syscall.OPEN_EXISTING, cSECURITY_SQOS_PRESENT|cSECURITY_ANONYMOUS, 0) | ||||
| 	if err != nil { | ||||
| 		syscall.Close(h) | ||||
| 		return nil, err | ||||
| 	} | ||||
| 	// Close the client handle. The server side of the instance will | ||||
| 	// still be busy, leading to ERROR_PIPE_BUSY instead of | ||||
| 	// ERROR_NOT_FOUND, as long as we don't close the server handle, | ||||
| 	// or disconnect the client with DisconnectNamedPipe. | ||||
| 	syscall.Close(h2) | ||||
| 	l := &win32PipeListener{ | ||||
| 		firstHandle:        h, | ||||
|   | ||||
							
								
								
									
										45
									
								
								vendor/github.com/Microsoft/hcsshim/container.go
									
									
									
										generated
									
									
										vendored
									
									
								
							
							
						
						
									
										45
									
								
								vendor/github.com/Microsoft/hcsshim/container.go
									
									
									
										generated
									
									
										vendored
									
									
								
							| @@ -4,6 +4,7 @@ import ( | ||||
| 	"encoding/json" | ||||
| 	"fmt" | ||||
| 	"os" | ||||
| 	"strconv" | ||||
| 	"sync" | ||||
| 	"syscall" | ||||
| 	"time" | ||||
| @@ -136,8 +137,26 @@ type ResourceModificationRequestResponse struct { | ||||
| // is merged in the CreateContainer call to HCS. | ||||
| var createContainerAdditionalJSON string | ||||
|  | ||||
| // currentContainerStarts is used to limit the number of concurrent container | ||||
| // starts. | ||||
| var currentContainerStarts containerStarts | ||||
|  | ||||
| type containerStarts struct { | ||||
| 	maxParallel int | ||||
| 	inProgress  int | ||||
| 	sync.Mutex | ||||
| } | ||||
|  | ||||
| func init() { | ||||
| 	createContainerAdditionalJSON = os.Getenv("HCSSHIM_CREATECONTAINER_ADDITIONALJSON") | ||||
| 	mpsS := os.Getenv("HCSSHIM_MAX_PARALLEL_START") | ||||
| 	if len(mpsS) > 0 { | ||||
| 		mpsI, err := strconv.Atoi(mpsS) | ||||
| 		if err != nil || mpsI < 0 { | ||||
| 			return | ||||
| 		} | ||||
| 		currentContainerStarts.maxParallel = mpsI | ||||
| 	} | ||||
| } | ||||
|  | ||||
| // CreateContainer creates a new container with the given configuration but does not start it. | ||||
| @@ -325,6 +344,32 @@ func (container *container) Start() error { | ||||
| 		return makeContainerError(container, operation, "", ErrAlreadyClosed) | ||||
| 	} | ||||
|  | ||||
| 	// This is a very simple backoff-retry loop to limit the number | ||||
| 	// of parallel container starts if environment variable | ||||
| 	// HCSSHIM_MAX_PARALLEL_START is set to a positive integer. | ||||
| 	// It should generally only be used as a workaround to various | ||||
| 	// platform issues that exist between RS1 and RS4 as of Aug 2018. | ||||
| 	if currentContainerStarts.maxParallel > 0 { | ||||
| 		for { | ||||
| 			currentContainerStarts.Lock() | ||||
| 			if currentContainerStarts.inProgress < currentContainerStarts.maxParallel { | ||||
| 				currentContainerStarts.inProgress++ | ||||
| 				currentContainerStarts.Unlock() | ||||
| 				break | ||||
| 			} | ||||
| 			if currentContainerStarts.inProgress == currentContainerStarts.maxParallel { | ||||
| 				currentContainerStarts.Unlock() | ||||
| 				time.Sleep(100 * time.Millisecond) | ||||
| 			} | ||||
| 		} | ||||
| 		// Make sure we decrement the count when we are done. | ||||
| 		defer func() { | ||||
| 			currentContainerStarts.Lock() | ||||
| 			currentContainerStarts.inProgress-- | ||||
| 			currentContainerStarts.Unlock() | ||||
| 		}() | ||||
| 	} | ||||
|  | ||||
| 	var resultp *uint16 | ||||
| 	err := hcsStartComputeSystem(container.handle, "", &resultp) | ||||
| 	err = processAsyncHcsResult(err, resultp, container.callbackNumber, hcsNotificationSystemStartCompleted, &defaultTimeout) | ||||
|   | ||||
							
								
								
									
										36
									
								
								vendor/github.com/Microsoft/hcsshim/interface.go
									
									
									
										generated
									
									
										vendored
									
									
								
							
							
						
						
									
										36
									
								
								vendor/github.com/Microsoft/hcsshim/interface.go
									
									
									
										generated
									
									
										vendored
									
									
								
							| @@ -6,6 +6,30 @@ import ( | ||||
| 	"time" | ||||
| ) | ||||
|  | ||||
| // RegistryKey is used to specify registry key name | ||||
| type RegistryKey struct { | ||||
| 	Hive     string | ||||
| 	Name     string | ||||
| 	Volatile bool `json:",omitempty"` | ||||
| } | ||||
|  | ||||
| // RegistryKey is used to specify registry key name | ||||
| type RegistryValue struct { | ||||
| 	Key         RegistryKey | ||||
| 	Name        string | ||||
| 	Type        string | ||||
| 	StringValue string  `json:",omitempty"` | ||||
| 	BinaryValue []byte  `json:",omitempty"` | ||||
| 	DWordValue  *uint32 `json:",omitempty"` | ||||
| 	QWordValue  *uint64 `json:",omitempty"` | ||||
| 	CustomType  *uint32 `json:",omitempty"` | ||||
| } | ||||
|  | ||||
| type RegistryChanges struct { | ||||
| 	AddValues  []RegistryValue `json:",omitempty"` | ||||
| 	DeleteKeys []RegistryValue `json:",omitempty"` | ||||
| } | ||||
|  | ||||
| // ProcessConfig is used as both the input of Container.CreateProcess | ||||
| // and to convert the parameters to JSON for passing onto the HCS | ||||
| type ProcessConfig struct { | ||||
| @@ -36,6 +60,8 @@ type MappedDir struct { | ||||
| 	BandwidthMaximum  uint64 | ||||
| 	IOPSMaximum       uint64 | ||||
| 	CreateInUtilityVM bool | ||||
| 	// LinuxMetadata - Support added in 1803/RS4+. | ||||
| 	LinuxMetadata bool `json:",omitempty"` | ||||
| } | ||||
|  | ||||
| type MappedPipe struct { | ||||
| @@ -62,6 +88,14 @@ type MappedVirtualDisk struct { | ||||
| 	AttachOnly        bool   `json:",omitempty:` | ||||
| } | ||||
|  | ||||
| // AssignedDevice represents a device that has been directly assigned to a container | ||||
| // | ||||
| // NOTE: Support added in RS5 | ||||
| type AssignedDevice struct { | ||||
| 	//  InterfaceClassGUID of the device to assign to container. | ||||
| 	InterfaceClassGUID string `json:"InterfaceClassGuid,omitempty"` | ||||
| } | ||||
|  | ||||
| // ContainerConfig is used as both the input of CreateContainer | ||||
| // and to convert the parameters to JSON for passing onto the HCS | ||||
| type ContainerConfig struct { | ||||
| @@ -93,6 +127,8 @@ type ContainerConfig struct { | ||||
| 	ContainerType               string              `json:",omitempty"` // "Linux" for Linux containers on Windows. Omitted otherwise. | ||||
| 	TerminateOnLastHandleClosed bool                `json:",omitempty"` // Should HCS terminate the container once all handles have been closed | ||||
| 	MappedVirtualDisks          []MappedVirtualDisk `json:",omitempty"` // Array of virtual disks to mount at start | ||||
| 	AssignedDevices             []AssignedDevice    `json:",omitempty"` // Array of devices to assign. NOTE: Support added in RS5 | ||||
| 	RegistryChanges             *RegistryChanges    `json:",omitempty"` // Registry changes to be applied to the container | ||||
| } | ||||
|  | ||||
| type ComputeSystemQuery struct { | ||||
|   | ||||
							
								
								
									
										2
									
								
								vendor/github.com/Microsoft/hcsshim/legacy.go
									
									
									
										generated
									
									
										vendored
									
									
								
							
							
						
						
									
										2
									
								
								vendor/github.com/Microsoft/hcsshim/legacy.go
									
									
									
										generated
									
									
										vendored
									
									
								
							| @@ -283,7 +283,7 @@ func (r *legacyLayerReader) Next() (path string, size int64, fileInfo *winio.Fil | ||||
| 		if err != nil { | ||||
| 			return | ||||
| 		} | ||||
| 		fileInfo.FileAttributes = uintptr(attr) | ||||
| 		fileInfo.FileAttributes = attr | ||||
| 		beginning := int64(4) | ||||
|  | ||||
| 		// Find the accurate file size. | ||||
|   | ||||
		Reference in New Issue
	
	Block a user
	 John Howard
					John Howard