Browse code

Revendor microsoft/go-winio @ v0.4.4

Signed-off-by: John Howard <jhoward@microsoft.com>

John Howard authored on 2017/07/19 11:09:32
Showing 5 changed files
... ...
@@ -13,7 +13,43 @@
13 13
 // operations. The downside of safe-mode is that operations are slower as
14 14
 // a new service utility VM has to be started and torn-down when needed.
15 15
 //
16
-// To enable global mode, run with --storage-opt lcow.globalmode=true
16
+// Options (needs official documentation, but lets get full functionality first...) @jhowardmsft
17
+//
18
+// The following options are read by the graphdriver itself:
19
+//
20
+//   * lcow.globalmode - Enables global service VM Mode
21
+//        -- Possible values:     true/false
22
+//        -- Default if omitted:  false
23
+//
24
+//   * lcow.sandboxsize - Specifies a custom sandbox size in GB for starting a container
25
+//        -- Possible values:      >= default sandbox size (opengcs defined, currently 20)
26
+//        -- Default if ommitted:  20
27
+//
28
+// The following options are read by opengcs:
29
+//
30
+//   * lcow.kirdpath - Specifies a custom path to a kernel/initrd pair
31
+//        -- Possible values:      Any local path that is not a mapped drive
32
+//        -- Default if ommitted:  %ProgramFiles%\Linux Containers
33
+//
34
+//   * lcow.kernel - Specifies a custom kernel file located in the `lcow.kirdpath` path
35
+//        -- Possible values:      Any valid filename
36
+//        -- Default if ommitted:  bootx64.efi
37
+//
38
+//   * lcow.initrd - Specifies a custom initrd file located in the `lcow.kirdpath` path
39
+//        -- Possible values:      Any valid filename
40
+//        -- Default if ommitted:  initrd.img
41
+//
42
+//   * lcow.bootparameters - Specifies additional boot parameters for booting in kernel+initrd mode
43
+//        -- Possible values:      Any valid linux kernel boot options
44
+//        -- Default if ommitted:  <nil>
45
+//
46
+//   * lcow.vhdx - Specifies a custom vhdx file to boot (instead of a kernel+initrd)
47
+//        -- Possible values:      Any valid filename
48
+//        -- Default if ommitted:  C:\Program Files\Linux Containers\uvm.vhdx
49
+//
50
+//   * lcow.timeout - Specifies a timeout for utility VM operations in seconds
51
+//        -- Possible values:      >=0
52
+//        -- Default if ommitted:  300
17 53
 
18 54
 // TODO: Grab logs from SVM at terminate or errors
19 55
 
... ...
@@ -1,7 +1,7 @@
1 1
 # the following lines are in sorted order, FYI
2 2
 github.com/Azure/go-ansiterm 19f72df4d05d31cbe1c56bfc8045c96babff6c7e
3 3
 github.com/Microsoft/hcsshim v0.6.1
4
-github.com/Microsoft/go-winio v0.4.2
4
+github.com/Microsoft/go-winio v0.4.4
5 5
 github.com/moby/buildkit da2b9dc7dab99e824b2b1067ad7d0523e32dd2d9 https://github.com/dmcgowan/buildkit.git
6 6
 github.com/davecgh/go-spew 346938d642f2ec3594ed81d874461961cd0faa76
7 7
 github.com/docker/libtrust 9cbd2a1374f46905c68a4eb3694a130610adc62a
... ...
@@ -23,6 +23,13 @@ type atomicBool int32
23 23
 func (b *atomicBool) isSet() bool { return atomic.LoadInt32((*int32)(b)) != 0 }
24 24
 func (b *atomicBool) setFalse()   { atomic.StoreInt32((*int32)(b), 0) }
25 25
 func (b *atomicBool) setTrue()    { atomic.StoreInt32((*int32)(b), 1) }
26
+func (b *atomicBool) swap(new bool) bool {
27
+	var newInt int32
28
+	if new {
29
+		newInt = 1
30
+	}
31
+	return atomic.SwapInt32((*int32)(b), newInt) == 1
32
+}
26 33
 
27 34
 const (
28 35
 	cFILE_SKIP_COMPLETION_PORT_ON_SUCCESS = 1
... ...
@@ -71,7 +78,7 @@ func initIo() {
71 71
 type win32File struct {
72 72
 	handle        syscall.Handle
73 73
 	wg            sync.WaitGroup
74
-	closing       bool
74
+	closing       atomicBool
75 75
 	readDeadline  deadlineHandler
76 76
 	writeDeadline deadlineHandler
77 77
 }
... ...
@@ -107,9 +114,9 @@ func MakeOpenFile(h syscall.Handle) (io.ReadWriteCloser, error) {
107 107
 
108 108
 // closeHandle closes the resources associated with a Win32 handle
109 109
 func (f *win32File) closeHandle() {
110
-	if !f.closing {
110
+	// Atomically set that we are closing, releasing the resources only once.
111
+	if !f.closing.swap(true) {
111 112
 		// cancel all IO and wait for it to complete
112
-		f.closing = true
113 113
 		cancelIoEx(f.handle, nil)
114 114
 		f.wg.Wait()
115 115
 		// at this point, no new IO can start
... ...
@@ -127,10 +134,10 @@ func (f *win32File) Close() error {
127 127
 // prepareIo prepares for a new IO operation.
128 128
 // The caller must call f.wg.Done() when the IO is finished, prior to Close() returning.
129 129
 func (f *win32File) prepareIo() (*ioOperation, error) {
130
-	f.wg.Add(1)
131
-	if f.closing {
130
+	if f.closing.isSet() {
132 131
 		return nil, ErrFileClosed
133 132
 	}
133
+	f.wg.Add(1)
134 134
 	c := &ioOperation{}
135 135
 	c.ch = make(chan ioResult)
136 136
 	return c, nil
... ...
@@ -159,7 +166,7 @@ func (f *win32File) asyncIo(c *ioOperation, d *deadlineHandler, bytes uint32, er
159 159
 		return int(bytes), err
160 160
 	}
161 161
 
162
-	if f.closing {
162
+	if f.closing.isSet() {
163 163
 		cancelIoEx(f.handle, &c.o)
164 164
 	}
165 165
 
... ...
@@ -175,7 +182,7 @@ func (f *win32File) asyncIo(c *ioOperation, d *deadlineHandler, bytes uint32, er
175 175
 	case r = <-c.ch:
176 176
 		err = r.err
177 177
 		if err == syscall.ERROR_OPERATION_ABORTED {
178
-			if f.closing {
178
+			if f.closing.isSet() {
179 179
 				err = ErrFileClosed
180 180
 			}
181 181
 		}
182 182
new file mode 100644
... ...
@@ -0,0 +1,82 @@
0
+// +build windows
1
+
2
+package vhd
3
+
4
+import "syscall"
5
+
6
+//go:generate go run mksyscall_windows.go -output zvhd.go vhd.go
7
+
8
+//sys createVirtualDisk(virtualStorageType *virtualStorageType, path string, virtualDiskAccessMask uint32, securityDescriptor *uintptr, flags uint32, providerSpecificFlags uint32, parameters *createVirtualDiskParameters, o *syscall.Overlapped, handle *syscall.Handle) (err error) [failretval != 0] = VirtDisk.CreateVirtualDisk
9
+
10
+type virtualStorageType struct {
11
+	DeviceID uint32
12
+	VendorID [16]byte
13
+}
14
+
15
+const virtualDiskAccessNONE uint32 = 0
16
+const virtualDiskAccessATTACHRO uint32 = 65536
17
+const virtualDiskAccessATTACHRW uint32 = 131072
18
+const virtualDiskAccessDETACH uint32 = 262144
19
+const virtualDiskAccessGETINFO uint32 = 524288
20
+const virtualDiskAccessCREATE uint32 = 1048576
21
+const virtualDiskAccessMETAOPS uint32 = 2097152
22
+const virtualDiskAccessREAD uint32 = 851968
23
+const virtualDiskAccessALL uint32 = 4128768
24
+const virtualDiskAccessWRITABLE uint32 = 3276800
25
+
26
+const createVirtualDiskFlagNone uint32 = 0
27
+const createVirtualDiskFlagFullPhysicalAllocation uint32 = 1
28
+const createVirtualDiskFlagPreventWritesToSourceDisk uint32 = 2
29
+const createVirtualDiskFlagDoNotCopyMetadataFromParent uint32 = 4
30
+
31
+type version2 struct {
32
+	UniqueID                 [16]byte // GUID
33
+	MaximumSize              uint64
34
+	BlockSizeInBytes         uint32
35
+	SectorSizeInBytes        uint32
36
+	ParentPath               *uint16 // string
37
+	SourcePath               *uint16 // string
38
+	OpenFlags                uint32
39
+	ParentVirtualStorageType virtualStorageType
40
+	SourceVirtualStorageType virtualStorageType
41
+	ResiliencyGUID           [16]byte // GUID
42
+}
43
+
44
+type createVirtualDiskParameters struct {
45
+	Version  uint32 // Must always be set to 2
46
+	Version2 version2
47
+}
48
+
49
+// CreateVhdx will create a simple vhdx file at the given path using default values.
50
+func CreateVhdx(path string, maxSizeInGb, blockSizeInMb uint32) error {
51
+	var defaultType virtualStorageType
52
+
53
+	parameters := createVirtualDiskParameters{
54
+		Version: 2,
55
+		Version2: version2{
56
+			MaximumSize:      uint64(maxSizeInGb) * 1024 * 1024 * 1024,
57
+			BlockSizeInBytes: blockSizeInMb * 1024 * 1024,
58
+		},
59
+	}
60
+
61
+	var handle syscall.Handle
62
+
63
+	if err := createVirtualDisk(
64
+		&defaultType,
65
+		path,
66
+		virtualDiskAccessNONE,
67
+		nil,
68
+		createVirtualDiskFlagNone,
69
+		0,
70
+		&parameters,
71
+		nil,
72
+		&handle); err != nil {
73
+		return err
74
+	}
75
+
76
+	if err := syscall.CloseHandle(handle); err != nil {
77
+		return err
78
+	}
79
+
80
+	return nil
81
+}
0 82
new file mode 100644
... ...
@@ -0,0 +1,64 @@
0
+// MACHINE GENERATED BY 'go generate' COMMAND; DO NOT EDIT
1
+
2
+package vhd
3
+
4
+import (
5
+	"syscall"
6
+	"unsafe"
7
+
8
+	"golang.org/x/sys/windows"
9
+)
10
+
11
+var _ unsafe.Pointer
12
+
13
+// Do the interface allocations only once for common
14
+// Errno values.
15
+const (
16
+	errnoERROR_IO_PENDING = 997
17
+)
18
+
19
+var (
20
+	errERROR_IO_PENDING error = syscall.Errno(errnoERROR_IO_PENDING)
21
+)
22
+
23
+// errnoErr returns common boxed Errno values, to prevent
24
+// allocations at runtime.
25
+func errnoErr(e syscall.Errno) error {
26
+	switch e {
27
+	case 0:
28
+		return nil
29
+	case errnoERROR_IO_PENDING:
30
+		return errERROR_IO_PENDING
31
+	}
32
+	// TODO: add more here, after collecting data on the common
33
+	// error values see on Windows. (perhaps when running
34
+	// all.bat?)
35
+	return e
36
+}
37
+
38
+var (
39
+	modVirtDisk = windows.NewLazySystemDLL("VirtDisk.dll")
40
+
41
+	procCreateVirtualDisk = modVirtDisk.NewProc("CreateVirtualDisk")
42
+)
43
+
44
+func createVirtualDisk(virtualStorageType *virtualStorageType, path string, virtualDiskAccessMask uint32, securityDescriptor *uintptr, flags uint32, providerSpecificFlags uint32, parameters *createVirtualDiskParameters, o *syscall.Overlapped, handle *syscall.Handle) (err error) {
45
+	var _p0 *uint16
46
+	_p0, err = syscall.UTF16PtrFromString(path)
47
+	if err != nil {
48
+		return
49
+	}
50
+	return _createVirtualDisk(virtualStorageType, _p0, virtualDiskAccessMask, securityDescriptor, flags, providerSpecificFlags, parameters, o, handle)
51
+}
52
+
53
+func _createVirtualDisk(virtualStorageType *virtualStorageType, path *uint16, virtualDiskAccessMask uint32, securityDescriptor *uintptr, flags uint32, providerSpecificFlags uint32, parameters *createVirtualDiskParameters, o *syscall.Overlapped, handle *syscall.Handle) (err error) {
54
+	r1, _, e1 := syscall.Syscall9(procCreateVirtualDisk.Addr(), 9, uintptr(unsafe.Pointer(virtualStorageType)), uintptr(unsafe.Pointer(path)), uintptr(virtualDiskAccessMask), uintptr(unsafe.Pointer(securityDescriptor)), uintptr(flags), uintptr(providerSpecificFlags), uintptr(unsafe.Pointer(parameters)), uintptr(unsafe.Pointer(o)), uintptr(unsafe.Pointer(handle)))
55
+	if r1 != 0 {
56
+		if e1 != 0 {
57
+			err = errnoErr(e1)
58
+		} else {
59
+			err = syscall.EINVAL
60
+		}
61
+	}
62
+	return
63
+}