This also requires bumping winio.
Signed-off-by: Brian Goff <cpuguy83@gmail.com>
| ... | ... |
@@ -1,6 +1,6 @@ |
| 1 | 1 |
github.com/Azure/go-ansiterm d6e3b3328b783f23731bc4d058875b0371ff8109 |
| 2 |
-github.com/Microsoft/hcsshim 380508768ed2619a4777f268c6443017bb76b04e # v0.8.10 |
|
| 3 |
-github.com/Microsoft/go-winio 5b44b70ab3ab4d291a7c1d28afe7b4afeced0ed4 # v0.4.15 |
|
| 2 |
+github.com/Microsoft/hcsshim e811ee705ec77df2ae28857ade553043fb564d91 # v0.8.16 |
|
| 3 |
+github.com/Microsoft/go-winio d1ffc52c73318019ce58aaa5282588c52df029b7 # v0.4.16 |
|
| 4 | 4 |
github.com/docker/libtrust 9cbd2a1374f46905c68a4eb3694a130610adc62a |
| 5 | 5 |
github.com/golang/gddo 72a348e765d293ed6d1ded7b699591f14d6cd921 |
| 6 | 6 |
github.com/google/uuid 0cd6bf5da1e1c83f8b45653022c74f71af0538a4 # v1.1.1 |
| ... | ... |
@@ -429,10 +429,10 @@ type PipeConfig struct {
|
| 429 | 429 |
// when the pipe is in message mode. |
| 430 | 430 |
MessageMode bool |
| 431 | 431 |
|
| 432 |
- // InputBufferSize specifies the size the input buffer, in bytes. |
|
| 432 |
+ // InputBufferSize specifies the size of the input buffer, in bytes. |
|
| 433 | 433 |
InputBufferSize int32 |
| 434 | 434 |
|
| 435 |
- // OutputBufferSize specifies the size the input buffer, in bytes. |
|
| 435 |
+ // OutputBufferSize specifies the size of the output buffer, in bytes. |
|
| 436 | 436 |
OutputBufferSize int32 |
| 437 | 437 |
} |
| 438 | 438 |
|
| ... | ... |
@@ -2,150 +2,323 @@ |
| 2 | 2 |
|
| 3 | 3 |
package vhd |
| 4 | 4 |
|
| 5 |
-import "syscall" |
|
| 5 |
+import ( |
|
| 6 |
+ "fmt" |
|
| 7 |
+ "syscall" |
|
| 8 |
+ |
|
| 9 |
+ "github.com/Microsoft/go-winio/pkg/guid" |
|
| 10 |
+ "github.com/pkg/errors" |
|
| 11 |
+ "golang.org/x/sys/windows" |
|
| 12 |
+) |
|
| 6 | 13 |
|
| 7 | 14 |
//go:generate go run mksyscall_windows.go -output zvhd.go vhd.go |
| 8 | 15 |
|
| 9 |
-//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 |
|
| 10 |
-//sys openVirtualDisk(virtualStorageType *virtualStorageType, path string, virtualDiskAccessMask uint32, flags uint32, parameters *openVirtualDiskParameters, handle *syscall.Handle) (err error) [failretval != 0] = VirtDisk.OpenVirtualDisk |
|
| 11 |
-//sys detachVirtualDisk(handle syscall.Handle, flags uint32, providerSpecificFlags uint32) (err error) [failretval != 0] = VirtDisk.DetachVirtualDisk |
|
| 12 |
- |
|
| 13 |
-type virtualStorageType struct {
|
|
| 14 |
- DeviceID uint32 |
|
| 15 |
- VendorID [16]byte |
|
| 16 |
-} |
|
| 16 |
+//sys createVirtualDisk(virtualStorageType *VirtualStorageType, path string, virtualDiskAccessMask uint32, securityDescriptor *uintptr, createVirtualDiskFlags uint32, providerSpecificFlags uint32, parameters *CreateVirtualDiskParameters, overlapped *syscall.Overlapped, handle *syscall.Handle) (err error) [failretval != 0] = virtdisk.CreateVirtualDisk |
|
| 17 |
+//sys openVirtualDisk(virtualStorageType *VirtualStorageType, path string, virtualDiskAccessMask uint32, openVirtualDiskFlags uint32, parameters *OpenVirtualDiskParameters, handle *syscall.Handle) (err error) [failretval != 0] = virtdisk.OpenVirtualDisk |
|
| 18 |
+//sys attachVirtualDisk(handle syscall.Handle, securityDescriptor *uintptr, attachVirtualDiskFlag uint32, providerSpecificFlags uint32, parameters *AttachVirtualDiskParameters, overlapped *syscall.Overlapped) (err error) [failretval != 0] = virtdisk.AttachVirtualDisk |
|
| 19 |
+//sys detachVirtualDisk(handle syscall.Handle, detachVirtualDiskFlags uint32, providerSpecificFlags uint32) (err error) [failretval != 0] = virtdisk.DetachVirtualDisk |
|
| 20 |
+//sys getVirtualDiskPhysicalPath(handle syscall.Handle, diskPathSizeInBytes *uint32, buffer *uint16) (err error) [failretval != 0] = virtdisk.GetVirtualDiskPhysicalPath |
|
| 17 | 21 |
|
| 18 | 22 |
type ( |
| 19 |
- createVirtualDiskFlag uint32 |
|
| 20 |
- VirtualDiskAccessMask uint32 |
|
| 23 |
+ CreateVirtualDiskFlag uint32 |
|
| 21 | 24 |
VirtualDiskFlag uint32 |
| 25 |
+ AttachVirtualDiskFlag uint32 |
|
| 26 |
+ DetachVirtualDiskFlag uint32 |
|
| 27 |
+ VirtualDiskAccessMask uint32 |
|
| 22 | 28 |
) |
| 23 | 29 |
|
| 24 |
-const ( |
|
| 25 |
- // Flags for creating a VHD (not exported) |
|
| 26 |
- createVirtualDiskFlagNone createVirtualDiskFlag = 0 |
|
| 27 |
- createVirtualDiskFlagFullPhysicalAllocation createVirtualDiskFlag = 1 |
|
| 28 |
- createVirtualDiskFlagPreventWritesToSourceDisk createVirtualDiskFlag = 2 |
|
| 29 |
- createVirtualDiskFlagDoNotCopyMetadataFromParent createVirtualDiskFlag = 4 |
|
| 30 |
- |
|
| 31 |
- // Access Mask for opening a VHD |
|
| 32 |
- VirtualDiskAccessNone VirtualDiskAccessMask = 0 |
|
| 33 |
- VirtualDiskAccessAttachRO VirtualDiskAccessMask = 65536 |
|
| 34 |
- VirtualDiskAccessAttachRW VirtualDiskAccessMask = 131072 |
|
| 35 |
- VirtualDiskAccessDetach VirtualDiskAccessMask = 262144 |
|
| 36 |
- VirtualDiskAccessGetInfo VirtualDiskAccessMask = 524288 |
|
| 37 |
- VirtualDiskAccessCreate VirtualDiskAccessMask = 1048576 |
|
| 38 |
- VirtualDiskAccessMetaOps VirtualDiskAccessMask = 2097152 |
|
| 39 |
- VirtualDiskAccessRead VirtualDiskAccessMask = 851968 |
|
| 40 |
- VirtualDiskAccessAll VirtualDiskAccessMask = 4128768 |
|
| 41 |
- VirtualDiskAccessWritable VirtualDiskAccessMask = 3276800 |
|
| 42 |
- |
|
| 43 |
- // Flags for opening a VHD |
|
| 44 |
- OpenVirtualDiskFlagNone VirtualDiskFlag = 0 |
|
| 45 |
- OpenVirtualDiskFlagNoParents VirtualDiskFlag = 0x1 |
|
| 46 |
- OpenVirtualDiskFlagBlankFile VirtualDiskFlag = 0x2 |
|
| 47 |
- OpenVirtualDiskFlagBootDrive VirtualDiskFlag = 0x4 |
|
| 48 |
- OpenVirtualDiskFlagCachedIO VirtualDiskFlag = 0x8 |
|
| 49 |
- OpenVirtualDiskFlagCustomDiffChain VirtualDiskFlag = 0x10 |
|
| 50 |
- OpenVirtualDiskFlagParentCachedIO VirtualDiskFlag = 0x20 |
|
| 51 |
- OpenVirtualDiskFlagVhdSetFileOnly VirtualDiskFlag = 0x40 |
|
| 52 |
- OpenVirtualDiskFlagIgnoreRelativeParentLocator VirtualDiskFlag = 0x80 |
|
| 53 |
- OpenVirtualDiskFlagNoWriteHardening VirtualDiskFlag = 0x100 |
|
| 54 |
-) |
|
| 30 |
+type VirtualStorageType struct {
|
|
| 31 |
+ DeviceID uint32 |
|
| 32 |
+ VendorID guid.GUID |
|
| 33 |
+} |
|
| 55 | 34 |
|
| 56 |
-type createVersion2 struct {
|
|
| 57 |
- UniqueID [16]byte // GUID |
|
| 35 |
+type CreateVersion2 struct {
|
|
| 36 |
+ UniqueID guid.GUID |
|
| 58 | 37 |
MaximumSize uint64 |
| 59 | 38 |
BlockSizeInBytes uint32 |
| 60 | 39 |
SectorSizeInBytes uint32 |
| 40 |
+ PhysicalSectorSizeInByte uint32 |
|
| 61 | 41 |
ParentPath *uint16 // string |
| 62 | 42 |
SourcePath *uint16 // string |
| 63 | 43 |
OpenFlags uint32 |
| 64 |
- ParentVirtualStorageType virtualStorageType |
|
| 65 |
- SourceVirtualStorageType virtualStorageType |
|
| 66 |
- ResiliencyGUID [16]byte // GUID |
|
| 44 |
+ ParentVirtualStorageType VirtualStorageType |
|
| 45 |
+ SourceVirtualStorageType VirtualStorageType |
|
| 46 |
+ ResiliencyGUID guid.GUID |
|
| 67 | 47 |
} |
| 68 | 48 |
|
| 69 |
-type createVirtualDiskParameters struct {
|
|
| 49 |
+type CreateVirtualDiskParameters struct {
|
|
| 70 | 50 |
Version uint32 // Must always be set to 2 |
| 71 |
- Version2 createVersion2 |
|
| 51 |
+ Version2 CreateVersion2 |
|
| 72 | 52 |
} |
| 73 | 53 |
|
| 74 |
-type openVersion2 struct {
|
|
| 75 |
- GetInfoOnly int32 // bool but 4-byte aligned |
|
| 76 |
- ReadOnly int32 // bool but 4-byte aligned |
|
| 77 |
- ResiliencyGUID [16]byte // GUID |
|
| 54 |
+type OpenVersion2 struct {
|
|
| 55 |
+ GetInfoOnly bool |
|
| 56 |
+ ReadOnly bool |
|
| 57 |
+ ResiliencyGUID guid.GUID |
|
| 78 | 58 |
} |
| 79 | 59 |
|
| 80 |
-type openVirtualDiskParameters struct {
|
|
| 60 |
+type OpenVirtualDiskParameters struct {
|
|
| 81 | 61 |
Version uint32 // Must always be set to 2 |
| 82 |
- Version2 openVersion2 |
|
| 62 |
+ Version2 OpenVersion2 |
|
| 83 | 63 |
} |
| 84 | 64 |
|
| 85 |
-// CreateVhdx will create a simple vhdx file at the given path using default values. |
|
| 86 |
-func CreateVhdx(path string, maxSizeInGb, blockSizeInMb uint32) error {
|
|
| 87 |
- var ( |
|
| 88 |
- defaultType virtualStorageType |
|
| 89 |
- handle syscall.Handle |
|
| 90 |
- ) |
|
| 65 |
+type AttachVersion2 struct {
|
|
| 66 |
+ RestrictedOffset uint64 |
|
| 67 |
+ RestrictedLength uint64 |
|
| 68 |
+} |
|
| 69 |
+ |
|
| 70 |
+type AttachVirtualDiskParameters struct {
|
|
| 71 |
+ Version uint32 // Must always be set to 2 |
|
| 72 |
+ Version2 AttachVersion2 |
|
| 73 |
+} |
|
| 74 |
+ |
|
| 75 |
+const ( |
|
| 76 |
+ VIRTUAL_STORAGE_TYPE_DEVICE_VHDX = 0x3 |
|
| 77 |
+ |
|
| 78 |
+ // Access Mask for opening a VHD |
|
| 79 |
+ VirtualDiskAccessNone VirtualDiskAccessMask = 0x00000000 |
|
| 80 |
+ VirtualDiskAccessAttachRO VirtualDiskAccessMask = 0x00010000 |
|
| 81 |
+ VirtualDiskAccessAttachRW VirtualDiskAccessMask = 0x00020000 |
|
| 82 |
+ VirtualDiskAccessDetach VirtualDiskAccessMask = 0x00040000 |
|
| 83 |
+ VirtualDiskAccessGetInfo VirtualDiskAccessMask = 0x00080000 |
|
| 84 |
+ VirtualDiskAccessCreate VirtualDiskAccessMask = 0x00100000 |
|
| 85 |
+ VirtualDiskAccessMetaOps VirtualDiskAccessMask = 0x00200000 |
|
| 86 |
+ VirtualDiskAccessRead VirtualDiskAccessMask = 0x000d0000 |
|
| 87 |
+ VirtualDiskAccessAll VirtualDiskAccessMask = 0x003f0000 |
|
| 88 |
+ VirtualDiskAccessWritable VirtualDiskAccessMask = 0x00320000 |
|
| 91 | 89 |
|
| 92 |
- parameters := createVirtualDiskParameters{
|
|
| 90 |
+ // Flags for creating a VHD |
|
| 91 |
+ CreateVirtualDiskFlagNone CreateVirtualDiskFlag = 0x0 |
|
| 92 |
+ CreateVirtualDiskFlagFullPhysicalAllocation CreateVirtualDiskFlag = 0x1 |
|
| 93 |
+ CreateVirtualDiskFlagPreventWritesToSourceDisk CreateVirtualDiskFlag = 0x2 |
|
| 94 |
+ CreateVirtualDiskFlagDoNotCopyMetadataFromParent CreateVirtualDiskFlag = 0x4 |
|
| 95 |
+ CreateVirtualDiskFlagCreateBackingStorage CreateVirtualDiskFlag = 0x8 |
|
| 96 |
+ CreateVirtualDiskFlagUseChangeTrackingSourceLimit CreateVirtualDiskFlag = 0x10 |
|
| 97 |
+ CreateVirtualDiskFlagPreserveParentChangeTrackingState CreateVirtualDiskFlag = 0x20 |
|
| 98 |
+ CreateVirtualDiskFlagVhdSetUseOriginalBackingStorage CreateVirtualDiskFlag = 0x40 |
|
| 99 |
+ CreateVirtualDiskFlagSparseFile CreateVirtualDiskFlag = 0x80 |
|
| 100 |
+ CreateVirtualDiskFlagPmemCompatible CreateVirtualDiskFlag = 0x100 |
|
| 101 |
+ CreateVirtualDiskFlagSupportCompressedVolumes CreateVirtualDiskFlag = 0x200 |
|
| 102 |
+ |
|
| 103 |
+ // Flags for opening a VHD |
|
| 104 |
+ OpenVirtualDiskFlagNone VirtualDiskFlag = 0x00000000 |
|
| 105 |
+ OpenVirtualDiskFlagNoParents VirtualDiskFlag = 0x00000001 |
|
| 106 |
+ OpenVirtualDiskFlagBlankFile VirtualDiskFlag = 0x00000002 |
|
| 107 |
+ OpenVirtualDiskFlagBootDrive VirtualDiskFlag = 0x00000004 |
|
| 108 |
+ OpenVirtualDiskFlagCachedIO VirtualDiskFlag = 0x00000008 |
|
| 109 |
+ OpenVirtualDiskFlagCustomDiffChain VirtualDiskFlag = 0x00000010 |
|
| 110 |
+ OpenVirtualDiskFlagParentCachedIO VirtualDiskFlag = 0x00000020 |
|
| 111 |
+ OpenVirtualDiskFlagVhdsetFileOnly VirtualDiskFlag = 0x00000040 |
|
| 112 |
+ OpenVirtualDiskFlagIgnoreRelativeParentLocator VirtualDiskFlag = 0x00000080 |
|
| 113 |
+ OpenVirtualDiskFlagNoWriteHardening VirtualDiskFlag = 0x00000100 |
|
| 114 |
+ OpenVirtualDiskFlagSupportCompressedVolumes VirtualDiskFlag = 0x00000200 |
|
| 115 |
+ |
|
| 116 |
+ // Flags for attaching a VHD |
|
| 117 |
+ AttachVirtualDiskFlagNone AttachVirtualDiskFlag = 0x00000000 |
|
| 118 |
+ AttachVirtualDiskFlagReadOnly AttachVirtualDiskFlag = 0x00000001 |
|
| 119 |
+ AttachVirtualDiskFlagNoDriveLetter AttachVirtualDiskFlag = 0x00000002 |
|
| 120 |
+ AttachVirtualDiskFlagPermanentLifetime AttachVirtualDiskFlag = 0x00000004 |
|
| 121 |
+ AttachVirtualDiskFlagNoLocalHost AttachVirtualDiskFlag = 0x00000008 |
|
| 122 |
+ AttachVirtualDiskFlagNoSecurityDescriptor AttachVirtualDiskFlag = 0x00000010 |
|
| 123 |
+ AttachVirtualDiskFlagBypassDefaultEncryptionPolicy AttachVirtualDiskFlag = 0x00000020 |
|
| 124 |
+ AttachVirtualDiskFlagNonPnp AttachVirtualDiskFlag = 0x00000040 |
|
| 125 |
+ AttachVirtualDiskFlagRestrictedRange AttachVirtualDiskFlag = 0x00000080 |
|
| 126 |
+ AttachVirtualDiskFlagSinglePartition AttachVirtualDiskFlag = 0x00000100 |
|
| 127 |
+ AttachVirtualDiskFlagRegisterVolume AttachVirtualDiskFlag = 0x00000200 |
|
| 128 |
+ |
|
| 129 |
+ // Flags for detaching a VHD |
|
| 130 |
+ DetachVirtualDiskFlagNone DetachVirtualDiskFlag = 0x0 |
|
| 131 |
+) |
|
| 132 |
+ |
|
| 133 |
+// CreateVhdx is a helper function to create a simple vhdx file at the given path using |
|
| 134 |
+// default values. |
|
| 135 |
+func CreateVhdx(path string, maxSizeInGb, blockSizeInMb uint32) error {
|
|
| 136 |
+ params := CreateVirtualDiskParameters{
|
|
| 93 | 137 |
Version: 2, |
| 94 |
- Version2: createVersion2{
|
|
| 138 |
+ Version2: CreateVersion2{
|
|
| 95 | 139 |
MaximumSize: uint64(maxSizeInGb) * 1024 * 1024 * 1024, |
| 96 | 140 |
BlockSizeInBytes: blockSizeInMb * 1024 * 1024, |
| 97 | 141 |
}, |
| 98 | 142 |
} |
| 99 | 143 |
|
| 100 |
- if err := createVirtualDisk( |
|
| 101 |
- &defaultType, |
|
| 102 |
- path, |
|
| 103 |
- uint32(VirtualDiskAccessNone), |
|
| 104 |
- nil, |
|
| 105 |
- uint32(createVirtualDiskFlagNone), |
|
| 106 |
- 0, |
|
| 107 |
- ¶meters, |
|
| 108 |
- nil, |
|
| 109 |
- &handle); err != nil {
|
|
| 144 |
+ handle, err := CreateVirtualDisk(path, VirtualDiskAccessNone, CreateVirtualDiskFlagNone, ¶ms) |
|
| 145 |
+ if err != nil {
|
|
| 110 | 146 |
return err |
| 111 | 147 |
} |
| 112 | 148 |
|
| 113 | 149 |
if err := syscall.CloseHandle(handle); err != nil {
|
| 114 | 150 |
return err |
| 115 | 151 |
} |
| 152 |
+ return nil |
|
| 153 |
+} |
|
| 116 | 154 |
|
| 155 |
+// DetachVirtualDisk detaches a virtual hard disk by handle. |
|
| 156 |
+func DetachVirtualDisk(handle syscall.Handle) (err error) {
|
|
| 157 |
+ if err := detachVirtualDisk(handle, 0, 0); err != nil {
|
|
| 158 |
+ return errors.Wrap(err, "failed to detach virtual disk") |
|
| 159 |
+ } |
|
| 117 | 160 |
return nil |
| 118 | 161 |
} |
| 119 | 162 |
|
| 120 |
-// DetachVhd detaches a mounted container layer vhd found at `path`. |
|
| 163 |
+// DetachVhd detaches a vhd found at `path`. |
|
| 121 | 164 |
func DetachVhd(path string) error {
|
| 122 | 165 |
handle, err := OpenVirtualDisk( |
| 123 | 166 |
path, |
| 124 | 167 |
VirtualDiskAccessNone, |
| 125 |
- OpenVirtualDiskFlagCachedIO|OpenVirtualDiskFlagIgnoreRelativeParentLocator) |
|
| 168 |
+ OpenVirtualDiskFlagCachedIO|OpenVirtualDiskFlagIgnoreRelativeParentLocator, |
|
| 169 |
+ ) |
|
| 170 |
+ if err != nil {
|
|
| 171 |
+ return err |
|
| 172 |
+ } |
|
| 173 |
+ defer syscall.CloseHandle(handle) |
|
| 174 |
+ return DetachVirtualDisk(handle) |
|
| 175 |
+} |
|
| 176 |
+ |
|
| 177 |
+// AttachVirtualDisk attaches a virtual hard disk for use. |
|
| 178 |
+func AttachVirtualDisk(handle syscall.Handle, attachVirtualDiskFlag AttachVirtualDiskFlag, parameters *AttachVirtualDiskParameters) (err error) {
|
|
| 179 |
+ if parameters.Version != 2 {
|
|
| 180 |
+ return fmt.Errorf("only version 2 VHDs are supported, found version: %d", parameters.Version)
|
|
| 181 |
+ } |
|
| 182 |
+ if err := attachVirtualDisk( |
|
| 183 |
+ handle, |
|
| 184 |
+ nil, |
|
| 185 |
+ uint32(attachVirtualDiskFlag), |
|
| 186 |
+ 0, |
|
| 187 |
+ parameters, |
|
| 188 |
+ nil, |
|
| 189 |
+ ); err != nil {
|
|
| 190 |
+ return errors.Wrap(err, "failed to attach virtual disk") |
|
| 191 |
+ } |
|
| 192 |
+ return nil |
|
| 193 |
+} |
|
| 126 | 194 |
|
| 195 |
+// AttachVhd attaches a virtual hard disk at `path` for use. |
|
| 196 |
+func AttachVhd(path string) (err error) {
|
|
| 197 |
+ handle, err := OpenVirtualDisk( |
|
| 198 |
+ path, |
|
| 199 |
+ VirtualDiskAccessNone, |
|
| 200 |
+ OpenVirtualDiskFlagCachedIO|OpenVirtualDiskFlagIgnoreRelativeParentLocator, |
|
| 201 |
+ ) |
|
| 127 | 202 |
if err != nil {
|
| 128 | 203 |
return err |
| 129 | 204 |
} |
| 205 |
+ |
|
| 130 | 206 |
defer syscall.CloseHandle(handle) |
| 131 |
- return detachVirtualDisk(handle, 0, 0) |
|
| 207 |
+ params := AttachVirtualDiskParameters{Version: 2}
|
|
| 208 |
+ if err := AttachVirtualDisk( |
|
| 209 |
+ handle, |
|
| 210 |
+ AttachVirtualDiskFlagNone, |
|
| 211 |
+ ¶ms, |
|
| 212 |
+ ); err != nil {
|
|
| 213 |
+ return errors.Wrap(err, "failed to attach virtual disk") |
|
| 214 |
+ } |
|
| 215 |
+ return nil |
|
| 132 | 216 |
} |
| 133 | 217 |
|
| 134 | 218 |
// OpenVirtualDisk obtains a handle to a VHD opened with supplied access mask and flags. |
| 135 |
-func OpenVirtualDisk(path string, accessMask VirtualDiskAccessMask, flag VirtualDiskFlag) (syscall.Handle, error) {
|
|
| 219 |
+func OpenVirtualDisk(vhdPath string, virtualDiskAccessMask VirtualDiskAccessMask, openVirtualDiskFlags VirtualDiskFlag) (syscall.Handle, error) {
|
|
| 220 |
+ parameters := OpenVirtualDiskParameters{Version: 2}
|
|
| 221 |
+ handle, err := OpenVirtualDiskWithParameters( |
|
| 222 |
+ vhdPath, |
|
| 223 |
+ virtualDiskAccessMask, |
|
| 224 |
+ openVirtualDiskFlags, |
|
| 225 |
+ ¶meters, |
|
| 226 |
+ ) |
|
| 227 |
+ if err != nil {
|
|
| 228 |
+ return 0, err |
|
| 229 |
+ } |
|
| 230 |
+ return handle, nil |
|
| 231 |
+} |
|
| 232 |
+ |
|
| 233 |
+// OpenVirtualDiskWithParameters obtains a handle to a VHD opened with supplied access mask, flags and parameters. |
|
| 234 |
+func OpenVirtualDiskWithParameters(vhdPath string, virtualDiskAccessMask VirtualDiskAccessMask, openVirtualDiskFlags VirtualDiskFlag, parameters *OpenVirtualDiskParameters) (syscall.Handle, error) {
|
|
| 136 | 235 |
var ( |
| 137 |
- defaultType virtualStorageType |
|
| 138 | 236 |
handle syscall.Handle |
| 237 |
+ defaultType VirtualStorageType |
|
| 139 | 238 |
) |
| 140 |
- parameters := openVirtualDiskParameters{Version: 2}
|
|
| 239 |
+ if parameters.Version != 2 {
|
|
| 240 |
+ return handle, fmt.Errorf("only version 2 VHDs are supported, found version: %d", parameters.Version)
|
|
| 241 |
+ } |
|
| 141 | 242 |
if err := openVirtualDisk( |
| 142 | 243 |
&defaultType, |
| 244 |
+ vhdPath, |
|
| 245 |
+ uint32(virtualDiskAccessMask), |
|
| 246 |
+ uint32(openVirtualDiskFlags), |
|
| 247 |
+ parameters, |
|
| 248 |
+ &handle, |
|
| 249 |
+ ); err != nil {
|
|
| 250 |
+ return 0, errors.Wrap(err, "failed to open virtual disk") |
|
| 251 |
+ } |
|
| 252 |
+ return handle, nil |
|
| 253 |
+} |
|
| 254 |
+ |
|
| 255 |
+// CreateVirtualDisk creates a virtual harddisk and returns a handle to the disk. |
|
| 256 |
+func CreateVirtualDisk(path string, virtualDiskAccessMask VirtualDiskAccessMask, createVirtualDiskFlags CreateVirtualDiskFlag, parameters *CreateVirtualDiskParameters) (syscall.Handle, error) {
|
|
| 257 |
+ var ( |
|
| 258 |
+ handle syscall.Handle |
|
| 259 |
+ defaultType VirtualStorageType |
|
| 260 |
+ ) |
|
| 261 |
+ if parameters.Version != 2 {
|
|
| 262 |
+ return handle, fmt.Errorf("only version 2 VHDs are supported, found version: %d", parameters.Version)
|
|
| 263 |
+ } |
|
| 264 |
+ |
|
| 265 |
+ if err := createVirtualDisk( |
|
| 266 |
+ &defaultType, |
|
| 143 | 267 |
path, |
| 144 |
- uint32(accessMask), |
|
| 145 |
- uint32(flag), |
|
| 146 |
- ¶meters, |
|
| 147 |
- &handle); err != nil {
|
|
| 148 |
- return 0, err |
|
| 268 |
+ uint32(virtualDiskAccessMask), |
|
| 269 |
+ nil, |
|
| 270 |
+ uint32(createVirtualDiskFlags), |
|
| 271 |
+ 0, |
|
| 272 |
+ parameters, |
|
| 273 |
+ nil, |
|
| 274 |
+ &handle, |
|
| 275 |
+ ); err != nil {
|
|
| 276 |
+ return handle, errors.Wrap(err, "failed to create virtual disk") |
|
| 149 | 277 |
} |
| 150 | 278 |
return handle, nil |
| 151 | 279 |
} |
| 280 |
+ |
|
| 281 |
+// GetVirtualDiskPhysicalPath takes a handle to a virtual hard disk and returns the physical |
|
| 282 |
+// path of the disk on the machine. This path is in the form \\.\PhysicalDriveX where X is an integer |
|
| 283 |
+// that represents the particular enumeration of the physical disk on the caller's system. |
|
| 284 |
+func GetVirtualDiskPhysicalPath(handle syscall.Handle) (_ string, err error) {
|
|
| 285 |
+ var ( |
|
| 286 |
+ diskPathSizeInBytes uint32 = 256 * 2 // max path length 256 wide chars |
|
| 287 |
+ diskPhysicalPathBuf [256]uint16 |
|
| 288 |
+ ) |
|
| 289 |
+ if err := getVirtualDiskPhysicalPath( |
|
| 290 |
+ handle, |
|
| 291 |
+ &diskPathSizeInBytes, |
|
| 292 |
+ &diskPhysicalPathBuf[0], |
|
| 293 |
+ ); err != nil {
|
|
| 294 |
+ return "", errors.Wrap(err, "failed to get disk physical path") |
|
| 295 |
+ } |
|
| 296 |
+ return windows.UTF16ToString(diskPhysicalPathBuf[:]), nil |
|
| 297 |
+} |
|
| 298 |
+ |
|
| 299 |
+// CreateDiffVhd is a helper function to create a differencing virtual disk. |
|
| 300 |
+func CreateDiffVhd(diffVhdPath, baseVhdPath string, blockSizeInMB uint32) error {
|
|
| 301 |
+ // Setting `ParentPath` is how to signal to create a differencing disk. |
|
| 302 |
+ createParams := &CreateVirtualDiskParameters{
|
|
| 303 |
+ Version: 2, |
|
| 304 |
+ Version2: CreateVersion2{
|
|
| 305 |
+ ParentPath: windows.StringToUTF16Ptr(baseVhdPath), |
|
| 306 |
+ BlockSizeInBytes: blockSizeInMB * 1024 * 1024, |
|
| 307 |
+ OpenFlags: uint32(OpenVirtualDiskFlagCachedIO), |
|
| 308 |
+ }, |
|
| 309 |
+ } |
|
| 310 |
+ |
|
| 311 |
+ vhdHandle, err := CreateVirtualDisk( |
|
| 312 |
+ diffVhdPath, |
|
| 313 |
+ VirtualDiskAccessNone, |
|
| 314 |
+ CreateVirtualDiskFlagNone, |
|
| 315 |
+ createParams, |
|
| 316 |
+ ) |
|
| 317 |
+ if err != nil {
|
|
| 318 |
+ return fmt.Errorf("failed to create differencing vhd: %s", err)
|
|
| 319 |
+ } |
|
| 320 |
+ if err := syscall.CloseHandle(vhdHandle); err != nil {
|
|
| 321 |
+ return fmt.Errorf("failed to close differencing vhd handle: %s", err)
|
|
| 322 |
+ } |
|
| 323 |
+ return nil |
|
| 324 |
+} |
| ... | ... |
@@ -37,24 +37,26 @@ func errnoErr(e syscall.Errno) error {
|
| 37 | 37 |
} |
| 38 | 38 |
|
| 39 | 39 |
var ( |
| 40 |
- modVirtDisk = windows.NewLazySystemDLL("VirtDisk.dll")
|
|
| 40 |
+ modvirtdisk = windows.NewLazySystemDLL("virtdisk.dll")
|
|
| 41 | 41 |
|
| 42 |
- procCreateVirtualDisk = modVirtDisk.NewProc("CreateVirtualDisk")
|
|
| 43 |
- procOpenVirtualDisk = modVirtDisk.NewProc("OpenVirtualDisk")
|
|
| 44 |
- procDetachVirtualDisk = modVirtDisk.NewProc("DetachVirtualDisk")
|
|
| 42 |
+ procCreateVirtualDisk = modvirtdisk.NewProc("CreateVirtualDisk")
|
|
| 43 |
+ procOpenVirtualDisk = modvirtdisk.NewProc("OpenVirtualDisk")
|
|
| 44 |
+ procAttachVirtualDisk = modvirtdisk.NewProc("AttachVirtualDisk")
|
|
| 45 |
+ procDetachVirtualDisk = modvirtdisk.NewProc("DetachVirtualDisk")
|
|
| 46 |
+ procGetVirtualDiskPhysicalPath = modvirtdisk.NewProc("GetVirtualDiskPhysicalPath")
|
|
| 45 | 47 |
) |
| 46 | 48 |
|
| 47 |
-func createVirtualDisk(virtualStorageType *virtualStorageType, path string, virtualDiskAccessMask uint32, securityDescriptor *uintptr, flags uint32, providerSpecificFlags uint32, parameters *createVirtualDiskParameters, o *syscall.Overlapped, handle *syscall.Handle) (err error) {
|
|
| 49 |
+func createVirtualDisk(virtualStorageType *VirtualStorageType, path string, virtualDiskAccessMask uint32, securityDescriptor *uintptr, createVirtualDiskFlags uint32, providerSpecificFlags uint32, parameters *CreateVirtualDiskParameters, overlapped *syscall.Overlapped, handle *syscall.Handle) (err error) {
|
|
| 48 | 50 |
var _p0 *uint16 |
| 49 | 51 |
_p0, err = syscall.UTF16PtrFromString(path) |
| 50 | 52 |
if err != nil {
|
| 51 | 53 |
return |
| 52 | 54 |
} |
| 53 |
- return _createVirtualDisk(virtualStorageType, _p0, virtualDiskAccessMask, securityDescriptor, flags, providerSpecificFlags, parameters, o, handle) |
|
| 55 |
+ return _createVirtualDisk(virtualStorageType, _p0, virtualDiskAccessMask, securityDescriptor, createVirtualDiskFlags, providerSpecificFlags, parameters, overlapped, handle) |
|
| 54 | 56 |
} |
| 55 | 57 |
|
| 56 |
-func _createVirtualDisk(virtualStorageType *virtualStorageType, path *uint16, virtualDiskAccessMask uint32, securityDescriptor *uintptr, flags uint32, providerSpecificFlags uint32, parameters *createVirtualDiskParameters, o *syscall.Overlapped, handle *syscall.Handle) (err error) {
|
|
| 57 |
- 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))) |
|
| 58 |
+func _createVirtualDisk(virtualStorageType *VirtualStorageType, path *uint16, virtualDiskAccessMask uint32, securityDescriptor *uintptr, createVirtualDiskFlags uint32, providerSpecificFlags uint32, parameters *CreateVirtualDiskParameters, overlapped *syscall.Overlapped, handle *syscall.Handle) (err error) {
|
|
| 59 |
+ r1, _, e1 := syscall.Syscall9(procCreateVirtualDisk.Addr(), 9, uintptr(unsafe.Pointer(virtualStorageType)), uintptr(unsafe.Pointer(path)), uintptr(virtualDiskAccessMask), uintptr(unsafe.Pointer(securityDescriptor)), uintptr(createVirtualDiskFlags), uintptr(providerSpecificFlags), uintptr(unsafe.Pointer(parameters)), uintptr(unsafe.Pointer(overlapped)), uintptr(unsafe.Pointer(handle))) |
|
| 58 | 60 |
if r1 != 0 {
|
| 59 | 61 |
if e1 != 0 {
|
| 60 | 62 |
err = errnoErr(e1) |
| ... | ... |
@@ -65,17 +67,17 @@ func _createVirtualDisk(virtualStorageType *virtualStorageType, path *uint16, vi |
| 65 | 65 |
return |
| 66 | 66 |
} |
| 67 | 67 |
|
| 68 |
-func openVirtualDisk(virtualStorageType *virtualStorageType, path string, virtualDiskAccessMask uint32, flags uint32, parameters *openVirtualDiskParameters, handle *syscall.Handle) (err error) {
|
|
| 68 |
+func openVirtualDisk(virtualStorageType *VirtualStorageType, path string, virtualDiskAccessMask uint32, openVirtualDiskFlags uint32, parameters *OpenVirtualDiskParameters, handle *syscall.Handle) (err error) {
|
|
| 69 | 69 |
var _p0 *uint16 |
| 70 | 70 |
_p0, err = syscall.UTF16PtrFromString(path) |
| 71 | 71 |
if err != nil {
|
| 72 | 72 |
return |
| 73 | 73 |
} |
| 74 |
- return _openVirtualDisk(virtualStorageType, _p0, virtualDiskAccessMask, flags, parameters, handle) |
|
| 74 |
+ return _openVirtualDisk(virtualStorageType, _p0, virtualDiskAccessMask, openVirtualDiskFlags, parameters, handle) |
|
| 75 | 75 |
} |
| 76 | 76 |
|
| 77 |
-func _openVirtualDisk(virtualStorageType *virtualStorageType, path *uint16, virtualDiskAccessMask uint32, flags uint32, parameters *openVirtualDiskParameters, handle *syscall.Handle) (err error) {
|
|
| 78 |
- r1, _, e1 := syscall.Syscall6(procOpenVirtualDisk.Addr(), 6, uintptr(unsafe.Pointer(virtualStorageType)), uintptr(unsafe.Pointer(path)), uintptr(virtualDiskAccessMask), uintptr(flags), uintptr(unsafe.Pointer(parameters)), uintptr(unsafe.Pointer(handle))) |
|
| 77 |
+func _openVirtualDisk(virtualStorageType *VirtualStorageType, path *uint16, virtualDiskAccessMask uint32, openVirtualDiskFlags uint32, parameters *OpenVirtualDiskParameters, handle *syscall.Handle) (err error) {
|
|
| 78 |
+ r1, _, e1 := syscall.Syscall6(procOpenVirtualDisk.Addr(), 6, uintptr(unsafe.Pointer(virtualStorageType)), uintptr(unsafe.Pointer(path)), uintptr(virtualDiskAccessMask), uintptr(openVirtualDiskFlags), uintptr(unsafe.Pointer(parameters)), uintptr(unsafe.Pointer(handle))) |
|
| 79 | 79 |
if r1 != 0 {
|
| 80 | 80 |
if e1 != 0 {
|
| 81 | 81 |
err = errnoErr(e1) |
| ... | ... |
@@ -86,8 +88,32 @@ func _openVirtualDisk(virtualStorageType *virtualStorageType, path *uint16, virt |
| 86 | 86 |
return |
| 87 | 87 |
} |
| 88 | 88 |
|
| 89 |
-func detachVirtualDisk(handle syscall.Handle, flags uint32, providerSpecificFlags uint32) (err error) {
|
|
| 90 |
- r1, _, e1 := syscall.Syscall(procDetachVirtualDisk.Addr(), 3, uintptr(handle), uintptr(flags), uintptr(providerSpecificFlags)) |
|
| 89 |
+func attachVirtualDisk(handle syscall.Handle, securityDescriptor *uintptr, attachVirtualDiskFlag uint32, providerSpecificFlags uint32, parameters *AttachVirtualDiskParameters, overlapped *syscall.Overlapped) (err error) {
|
|
| 90 |
+ r1, _, e1 := syscall.Syscall6(procAttachVirtualDisk.Addr(), 6, uintptr(handle), uintptr(unsafe.Pointer(securityDescriptor)), uintptr(attachVirtualDiskFlag), uintptr(providerSpecificFlags), uintptr(unsafe.Pointer(parameters)), uintptr(unsafe.Pointer(overlapped))) |
|
| 91 |
+ if r1 != 0 {
|
|
| 92 |
+ if e1 != 0 {
|
|
| 93 |
+ err = errnoErr(e1) |
|
| 94 |
+ } else {
|
|
| 95 |
+ err = syscall.EINVAL |
|
| 96 |
+ } |
|
| 97 |
+ } |
|
| 98 |
+ return |
|
| 99 |
+} |
|
| 100 |
+ |
|
| 101 |
+func detachVirtualDisk(handle syscall.Handle, detachVirtualDiskFlags uint32, providerSpecificFlags uint32) (err error) {
|
|
| 102 |
+ r1, _, e1 := syscall.Syscall(procDetachVirtualDisk.Addr(), 3, uintptr(handle), uintptr(detachVirtualDiskFlags), uintptr(providerSpecificFlags)) |
|
| 103 |
+ if r1 != 0 {
|
|
| 104 |
+ if e1 != 0 {
|
|
| 105 |
+ err = errnoErr(e1) |
|
| 106 |
+ } else {
|
|
| 107 |
+ err = syscall.EINVAL |
|
| 108 |
+ } |
|
| 109 |
+ } |
|
| 110 |
+ return |
|
| 111 |
+} |
|
| 112 |
+ |
|
| 113 |
+func getVirtualDiskPhysicalPath(handle syscall.Handle, diskPathSizeInBytes *uint32, buffer *uint16) (err error) {
|
|
| 114 |
+ r1, _, e1 := syscall.Syscall(procGetVirtualDiskPhysicalPath.Addr(), 3, uintptr(handle), uintptr(unsafe.Pointer(diskPathSizeInBytes)), uintptr(unsafe.Pointer(buffer))) |
|
| 91 | 115 |
if r1 != 0 {
|
| 92 | 116 |
if e1 != 0 {
|
| 93 | 117 |
err = errnoErr(e1) |
| ... | ... |
@@ -1,6 +1,6 @@ |
| 1 | 1 |
# hcsshim |
| 2 | 2 |
|
| 3 |
-[](https://ci.appveyor.com/project/WindowsVirtualization/hcsshim/branch/master) |
|
| 3 |
+[](https://github.com/microsoft/hcsshim/actions?query=branch%3Amaster) |
|
| 4 | 4 |
|
| 5 | 5 |
This package contains the Golang interface for using the Windows [Host Compute Service](https://techcommunity.microsoft.com/t5/containers/introducing-the-host-compute-service-hcs/ba-p/382332) (HCS) to launch and manage [Windows Containers](https://docs.microsoft.com/en-us/virtualization/windowscontainers/about/). It also contains other helpers and functions for managing Windows Containers such as the Golang interface for the Host Network Service (HNS). |
| 6 | 6 |
|
| ... | ... |
@@ -5,14 +5,15 @@ package options |
| 5 | 5 |
|
| 6 | 6 |
import ( |
| 7 | 7 |
fmt "fmt" |
| 8 |
- proto "github.com/gogo/protobuf/proto" |
|
| 9 |
- _ "github.com/gogo/protobuf/types" |
|
| 10 |
- github_com_gogo_protobuf_types "github.com/gogo/protobuf/types" |
|
| 11 | 8 |
io "io" |
| 12 | 9 |
math "math" |
| 13 | 10 |
reflect "reflect" |
| 14 | 11 |
strings "strings" |
| 15 | 12 |
time "time" |
| 13 |
+ |
|
| 14 |
+ proto "github.com/gogo/protobuf/proto" |
|
| 15 |
+ _ "github.com/gogo/protobuf/types" |
|
| 16 |
+ github_com_gogo_protobuf_types "github.com/gogo/protobuf/types" |
|
| 16 | 17 |
) |
| 17 | 18 |
|
| 18 | 19 |
// Reference imports to suppress errors if they are not otherwise used. |
| ... | ... |
@@ -115,7 +116,26 @@ type Options struct {
|
| 115 | 115 |
VmMemorySizeInMb int32 `protobuf:"varint,9,opt,name=vm_memory_size_in_mb,json=vmMemorySizeInMb,proto3" json:"vm_memory_size_in_mb,omitempty"` |
| 116 | 116 |
// GPUVHDPath is the path to the gpu vhd to add to the uvm |
| 117 | 117 |
// when a container requests a gpu |
| 118 |
- GPUVHDPath string `protobuf:"bytes,10,opt,name=GPUVHDPath,proto3" json:"GPUVHDPath,omitempty"` |
|
| 118 |
+ GPUVHDPath string `protobuf:"bytes,10,opt,name=GPUVHDPath,proto3" json:"GPUVHDPath,omitempty"` |
|
| 119 |
+ // scale_cpu_limits_to_sandbox indicates that container CPU limits should |
|
| 120 |
+ // be adjusted to account for the difference in number of cores between the |
|
| 121 |
+ // host and UVM. |
|
| 122 |
+ ScaleCpuLimitsToSandbox bool `protobuf:"varint,11,opt,name=scale_cpu_limits_to_sandbox,json=scaleCpuLimitsToSandbox,proto3" json:"scale_cpu_limits_to_sandbox,omitempty"` |
|
| 123 |
+ // default_container_scratch_size_in_gb is the default scratch size (sandbox.vhdx) |
|
| 124 |
+ // to be used for containers. Every container will get a sandbox of `size_in_gb` assigned |
|
| 125 |
+ // instead of the default of 20GB. |
|
| 126 |
+ DefaultContainerScratchSizeInGb int32 `protobuf:"varint,12,opt,name=default_container_scratch_size_in_gb,json=defaultContainerScratchSizeInGb,proto3" json:"default_container_scratch_size_in_gb,omitempty"` |
|
| 127 |
+ // default_vm_scratch_size_in_gb is the default scratch size (sandbox.vhdx) |
|
| 128 |
+ // to be used for the UVM. This only applies to WCOW as LCOW doesn't mount a scratch |
|
| 129 |
+ // specifically for the UVM. |
|
| 130 |
+ DefaultVmScratchSizeInGb int32 `protobuf:"varint,13,opt,name=default_vm_scratch_size_in_gb,json=defaultVmScratchSizeInGb,proto3" json:"default_vm_scratch_size_in_gb,omitempty"` |
|
| 131 |
+ // share_scratch specifies if we'd like to reuse scratch space between multiple containers. |
|
| 132 |
+ // This currently only affects LCOW. The sandbox containers scratch space is re-used for all |
|
| 133 |
+ // subsequent containers launched in the pod. |
|
| 134 |
+ ShareScratch bool `protobuf:"varint,14,opt,name=share_scratch,json=shareScratch,proto3" json:"share_scratch,omitempty"` |
|
| 135 |
+ //NCProxyAddr is the address of the network configuration proxy service. If omitted |
|
| 136 |
+ // the network is setup locally. |
|
| 137 |
+ NCProxyAddr string `protobuf:"bytes,15,opt,name=NCProxyAddr,proto3" json:"NCProxyAddr,omitempty"` |
|
| 119 | 138 |
XXX_NoUnkeyedLiteral struct{} `json:"-"`
|
| 120 | 139 |
XXX_unrecognized []byte `json:"-"` |
| 121 | 140 |
XXX_sizecache int32 `json:"-"` |
| ... | ... |
@@ -214,56 +234,64 @@ func init() {
|
| 214 | 214 |
} |
| 215 | 215 |
|
| 216 | 216 |
var fileDescriptor_b643df6839c75082 = []byte{
|
| 217 |
- // 775 bytes of a gzipped FileDescriptorProto |
|
| 218 |
- 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xa4, 0x54, 0xcd, 0x6f, 0xdb, 0x36, |
|
| 219 |
- 0x1c, 0xb5, 0x1a, 0x7f, 0xe9, 0xd7, 0x25, 0x75, 0x38, 0x1f, 0x84, 0x6c, 0xb3, 0x8d, 0xf4, 0xd0, |
|
| 220 |
- 0x14, 0x6b, 0xa4, 0xa4, 0x3b, 0xee, 0x34, 0xc7, 0xce, 0xaa, 0x61, 0x49, 0x04, 0x39, 0x6b, 0xf7, |
|
| 221 |
- 0x71, 0x20, 0xf4, 0xc1, 0xc8, 0x44, 0x4d, 0x51, 0x20, 0x69, 0x2f, 0xee, 0x69, 0x7f, 0xc2, 0xfe, |
|
| 222 |
- 0xa8, 0x1d, 0x72, 0xdc, 0x71, 0xc0, 0x80, 0x6c, 0xf5, 0x5f, 0x32, 0x90, 0x92, 0xd2, 0xad, 0x08, |
|
| 223 |
- 0x76, 0xe9, 0xc9, 0xd4, 0x7b, 0x8f, 0xef, 0xf7, 0xc1, 0x07, 0xc3, 0x45, 0x46, 0xd5, 0x7c, 0x19, |
|
| 224 |
- 0xbb, 0x09, 0x67, 0xde, 0x19, 0x4d, 0x04, 0x97, 0xfc, 0x4a, 0x79, 0xf3, 0x44, 0xca, 0x39, 0x65, |
|
| 225 |
- 0x5e, 0xc2, 0x52, 0x2f, 0xe1, 0xb9, 0x8a, 0x68, 0x4e, 0x44, 0x7a, 0xa8, 0xb1, 0x43, 0xb1, 0xcc, |
|
| 226 |
- 0xe7, 0x89, 0x3c, 0x5c, 0x1d, 0x7b, 0xbc, 0x50, 0x94, 0xe7, 0xd2, 0x2b, 0x11, 0xb7, 0x10, 0x5c, |
|
| 227 |
- 0x71, 0xd4, 0x7f, 0xa7, 0x77, 0x2b, 0x62, 0x75, 0xbc, 0xd7, 0xcf, 0x78, 0xc6, 0x8d, 0xc0, 0xd3, |
|
| 228 |
- 0xa7, 0x52, 0xbb, 0x37, 0xcc, 0x38, 0xcf, 0x16, 0xc4, 0x33, 0x5f, 0xf1, 0xf2, 0xca, 0x53, 0x94, |
|
| 229 |
- 0x11, 0xa9, 0x22, 0x56, 0x94, 0x82, 0xfd, 0xdf, 0x9a, 0xd0, 0xb9, 0x28, 0xab, 0xa0, 0x3e, 0xb4, |
|
| 230 |
- 0x52, 0x12, 0x2f, 0x33, 0xc7, 0x1a, 0x59, 0x07, 0xdd, 0xb0, 0xfc, 0x40, 0xa7, 0x00, 0xe6, 0x80, |
|
| 231 |
- 0xd5, 0xba, 0x20, 0xce, 0x83, 0x91, 0x75, 0xb0, 0xf3, 0xfc, 0x89, 0x7b, 0x5f, 0x0f, 0x6e, 0x65, |
|
| 232 |
- 0xe4, 0x4e, 0xb4, 0xfe, 0x72, 0x5d, 0x90, 0xd0, 0x4e, 0xeb, 0x23, 0x7a, 0x0c, 0xdb, 0x82, 0x64, |
|
| 233 |
- 0x54, 0x2a, 0xb1, 0xc6, 0x82, 0x73, 0xe5, 0x6c, 0x8d, 0xac, 0x03, 0x3b, 0xfc, 0xa8, 0x06, 0x43, |
|
| 234 |
- 0xce, 0x95, 0x16, 0xc9, 0x28, 0x4f, 0x63, 0x7e, 0x8d, 0x29, 0x8b, 0x32, 0xe2, 0x34, 0x4b, 0x51, |
|
| 235 |
- 0x05, 0xfa, 0x1a, 0x43, 0x4f, 0xa1, 0x57, 0x8b, 0x8a, 0x45, 0xa4, 0xae, 0xb8, 0x60, 0x4e, 0xcb, |
|
| 236 |
- 0xe8, 0x1e, 0x55, 0x78, 0x50, 0xc1, 0xe8, 0x27, 0xd8, 0xbd, 0xf3, 0x93, 0x7c, 0x11, 0xe9, 0xfe, |
|
| 237 |
- 0x9c, 0xb6, 0x99, 0xc1, 0xfd, 0xff, 0x19, 0x66, 0x55, 0xc5, 0xfa, 0x56, 0x58, 0xd7, 0xbc, 0x43, |
|
| 238 |
- 0x90, 0x07, 0xfd, 0x98, 0x73, 0x85, 0xaf, 0xe8, 0x82, 0x48, 0x33, 0x13, 0x2e, 0x22, 0x35, 0x77, |
|
| 239 |
- 0x3a, 0xa6, 0x97, 0x5d, 0xcd, 0x9d, 0x6a, 0x4a, 0x4f, 0x16, 0x44, 0x6a, 0x8e, 0x9e, 0x01, 0x5a, |
|
| 240 |
- 0x31, 0x5c, 0x08, 0x9e, 0x10, 0x29, 0xb9, 0xc0, 0x09, 0x5f, 0xe6, 0xca, 0xe9, 0x8e, 0xac, 0x83, |
|
| 241 |
- 0x56, 0xd8, 0x5b, 0xb1, 0xa0, 0x26, 0x4e, 0x34, 0x8e, 0x5c, 0xe8, 0xaf, 0x18, 0x66, 0x84, 0x71, |
|
| 242 |
- 0xb1, 0xc6, 0x92, 0xbe, 0x21, 0x98, 0xe6, 0x98, 0xc5, 0x8e, 0x5d, 0xeb, 0xcf, 0x0c, 0x35, 0xa3, |
|
| 243 |
- 0x6f, 0x88, 0x9f, 0x9f, 0xc5, 0x68, 0x00, 0xf0, 0x75, 0xf0, 0xdd, 0xcb, 0x17, 0x13, 0x5d, 0xcb, |
|
| 244 |
- 0x01, 0xd3, 0xc4, 0xbf, 0x90, 0xfd, 0xa7, 0x60, 0xdf, 0x3d, 0x0c, 0xb2, 0xa1, 0x75, 0x1e, 0xf8, |
|
| 245 |
- 0xc1, 0xb4, 0xd7, 0x40, 0x5d, 0x68, 0x9e, 0xfa, 0xdf, 0x4e, 0x7b, 0x16, 0xea, 0xc0, 0xd6, 0xf4, |
|
| 246 |
- 0xf2, 0x55, 0xef, 0xc1, 0xbe, 0x07, 0xbd, 0xf7, 0xe7, 0x47, 0x0f, 0xa1, 0x13, 0x84, 0x17, 0x27, |
|
| 247 |
- 0xd3, 0xd9, 0xac, 0xd7, 0x40, 0x3b, 0x00, 0x2f, 0x7e, 0x08, 0xa6, 0xe1, 0x4b, 0x7f, 0x76, 0x11, |
|
| 248 |
- 0xf6, 0xac, 0xfd, 0x3f, 0xb7, 0x60, 0xa7, 0x6a, 0x7f, 0x42, 0x54, 0x44, 0x17, 0x12, 0x7d, 0x06, |
|
| 249 |
- 0x60, 0x9e, 0x10, 0xe7, 0x11, 0x23, 0x26, 0x52, 0x76, 0x68, 0x1b, 0xe4, 0x3c, 0x62, 0x04, 0x9d, |
|
| 250 |
- 0x00, 0x24, 0x82, 0x44, 0x8a, 0xa4, 0x38, 0x52, 0x26, 0x56, 0x0f, 0x9f, 0xef, 0xb9, 0x65, 0x5c, |
|
| 251 |
- 0xdd, 0x3a, 0xae, 0xee, 0x65, 0x1d, 0xd7, 0x71, 0xf7, 0xe6, 0x76, 0xd8, 0xf8, 0xf5, 0xaf, 0xa1, |
|
| 252 |
- 0x15, 0xda, 0xd5, 0xbd, 0xaf, 0x14, 0xfa, 0x1c, 0xd0, 0x6b, 0x22, 0x72, 0xb2, 0xc0, 0x3a, 0xd7, |
|
| 253 |
- 0xf8, 0xf8, 0xe8, 0x08, 0xe7, 0xd2, 0x04, 0xab, 0x19, 0x3e, 0x2a, 0x19, 0xed, 0x70, 0x7c, 0x74, |
|
| 254 |
- 0x74, 0x2e, 0x91, 0x0b, 0x1f, 0x57, 0xcb, 0x4c, 0x38, 0x63, 0x54, 0xe1, 0x78, 0xad, 0x88, 0x34, |
|
| 255 |
- 0x09, 0x6b, 0x86, 0xbb, 0x25, 0x75, 0x62, 0x98, 0xb1, 0x26, 0xd0, 0x29, 0x8c, 0x2a, 0xfd, 0xcf, |
|
| 256 |
- 0x5c, 0xbc, 0xa6, 0x79, 0x86, 0x25, 0x51, 0xb8, 0x10, 0x74, 0x15, 0x29, 0x52, 0x5d, 0x6e, 0x99, |
|
| 257 |
- 0xcb, 0x9f, 0x96, 0xba, 0x57, 0xa5, 0x6c, 0x46, 0x54, 0x50, 0x8a, 0x4a, 0x9f, 0x09, 0x0c, 0xef, |
|
| 258 |
- 0xf1, 0x91, 0xf3, 0x48, 0x90, 0xb4, 0xb2, 0x69, 0x1b, 0x9b, 0x4f, 0xde, 0xb7, 0x99, 0x19, 0x4d, |
|
| 259 |
- 0xe9, 0xf2, 0x0c, 0xa0, 0x0a, 0x0e, 0xa6, 0xa9, 0x89, 0xd8, 0xf6, 0x78, 0x7b, 0x73, 0x3b, 0xb4, |
|
| 260 |
- 0xab, 0xb5, 0xfb, 0x93, 0xd0, 0xae, 0x04, 0x7e, 0x8a, 0x9e, 0x40, 0x6f, 0x29, 0x89, 0xf8, 0xcf, |
|
| 261 |
- 0x5a, 0xba, 0xa6, 0xc8, 0xb6, 0xc6, 0xdf, 0x2d, 0xe5, 0x31, 0x74, 0xc8, 0x35, 0x49, 0xb4, 0xa7, |
|
| 262 |
- 0xce, 0x95, 0x3d, 0x86, 0xcd, 0xed, 0xb0, 0x3d, 0xbd, 0x26, 0x89, 0x3f, 0x09, 0xdb, 0x9a, 0xf2, |
|
| 263 |
- 0xd3, 0x71, 0x7a, 0xf3, 0x76, 0xd0, 0xf8, 0xe3, 0xed, 0xa0, 0xf1, 0xcb, 0x66, 0x60, 0xdd, 0x6c, |
|
| 264 |
- 0x06, 0xd6, 0xef, 0x9b, 0x81, 0xf5, 0xf7, 0x66, 0x60, 0xfd, 0xf8, 0xcd, 0x87, 0xff, 0xb9, 0x7d, |
|
| 265 |
- 0x59, 0xfd, 0x7e, 0xdf, 0x88, 0xdb, 0xe6, 0xdd, 0xbf, 0xf8, 0x27, 0x00, 0x00, 0xff, 0xff, 0x75, |
|
| 266 |
- 0x1f, 0x14, 0xf4, 0x33, 0x05, 0x00, 0x00, |
|
| 217 |
+ // 899 bytes of a gzipped FileDescriptorProto |
|
| 218 |
+ 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xa4, 0x94, 0x5b, 0x6f, 0xdb, 0x36, |
|
| 219 |
+ 0x18, 0x86, 0xad, 0x26, 0x71, 0xac, 0x2f, 0x71, 0xe2, 0x70, 0x06, 0x26, 0xa4, 0xab, 0x6d, 0xa4, |
|
| 220 |
+ 0x03, 0x9a, 0x62, 0x8d, 0x94, 0x74, 0x97, 0x1b, 0x30, 0xd4, 0x87, 0xb4, 0x1e, 0x9a, 0x44, 0x90, |
|
| 221 |
+ 0xb3, 0x74, 0x87, 0x0b, 0x42, 0x07, 0x5a, 0x16, 0x6a, 0x8a, 0x02, 0x49, 0x7b, 0x71, 0xaf, 0xf6, |
|
| 222 |
+ 0x13, 0xf6, 0xb3, 0x72, 0xb9, 0xcb, 0x0d, 0x03, 0xb2, 0xd5, 0xbf, 0x64, 0x10, 0x45, 0xb9, 0x5d, |
|
| 223 |
+ 0x10, 0xec, 0x66, 0x57, 0xa6, 0xde, 0xef, 0xe1, 0xcb, 0x8f, 0x87, 0xd7, 0x70, 0x11, 0x27, 0x72, |
|
| 224 |
+ 0x32, 0x0b, 0xec, 0x90, 0x51, 0xe7, 0x2c, 0x09, 0x39, 0x13, 0x6c, 0x2c, 0x9d, 0x49, 0x28, 0xc4, |
|
| 225 |
+ 0x24, 0xa1, 0x4e, 0x48, 0x23, 0x27, 0x64, 0xa9, 0xf4, 0x93, 0x94, 0xf0, 0xe8, 0x28, 0xd7, 0x8e, |
|
| 226 |
+ 0xf8, 0x2c, 0x9d, 0x84, 0xe2, 0x68, 0x7e, 0xe2, 0xb0, 0x4c, 0x26, 0x2c, 0x15, 0x4e, 0xa1, 0xd8, |
|
| 227 |
+ 0x19, 0x67, 0x92, 0xa1, 0xe6, 0x07, 0xde, 0xd6, 0x85, 0xf9, 0xc9, 0x7e, 0x33, 0x66, 0x31, 0x53, |
|
| 228 |
+ 0x80, 0x93, 0x8f, 0x0a, 0x76, 0xbf, 0x1d, 0x33, 0x16, 0x4f, 0x89, 0xa3, 0xbe, 0x82, 0xd9, 0xd8, |
|
| 229 |
+ 0x91, 0x09, 0x25, 0x42, 0xfa, 0x34, 0x2b, 0x80, 0x83, 0x3f, 0xaa, 0xb0, 0x79, 0x51, 0xac, 0x82, |
|
| 230 |
+ 0x9a, 0xb0, 0x11, 0x91, 0x60, 0x16, 0x5b, 0x46, 0xc7, 0x38, 0xac, 0x79, 0xc5, 0x07, 0x3a, 0x05, |
|
| 231 |
+ 0x50, 0x03, 0x2c, 0x17, 0x19, 0xb1, 0x1e, 0x74, 0x8c, 0xc3, 0x9d, 0xe7, 0x4f, 0xec, 0xfb, 0x7a, |
|
| 232 |
+ 0xb0, 0xb5, 0x91, 0xdd, 0xcf, 0xf9, 0xcb, 0x45, 0x46, 0x3c, 0x33, 0x2a, 0x87, 0xe8, 0x31, 0xd4, |
|
| 233 |
+ 0x39, 0x89, 0x13, 0x21, 0xf9, 0x02, 0x73, 0xc6, 0xa4, 0xb5, 0xd6, 0x31, 0x0e, 0x4d, 0x6f, 0xbb, |
|
| 234 |
+ 0x14, 0x3d, 0xc6, 0x64, 0x0e, 0x09, 0x3f, 0x8d, 0x02, 0x76, 0x8d, 0x13, 0xea, 0xc7, 0xc4, 0x5a, |
|
| 235 |
+ 0x2f, 0x20, 0x2d, 0x0e, 0x73, 0x0d, 0x3d, 0x85, 0x46, 0x09, 0x65, 0x53, 0x5f, 0x8e, 0x19, 0xa7, |
|
| 236 |
+ 0xd6, 0x86, 0xe2, 0x76, 0xb5, 0xee, 0x6a, 0x19, 0xfd, 0x04, 0x7b, 0x2b, 0x3f, 0xc1, 0xa6, 0x7e, |
|
| 237 |
+ 0xde, 0x9f, 0x55, 0x55, 0x7b, 0xb0, 0xff, 0x7b, 0x0f, 0x23, 0xbd, 0x62, 0x39, 0xcb, 0x2b, 0xd7, |
|
| 238 |
+ 0x5c, 0x29, 0xc8, 0x81, 0x66, 0xc0, 0x98, 0xc4, 0xe3, 0x64, 0x4a, 0x84, 0xda, 0x13, 0xce, 0x7c, |
|
| 239 |
+ 0x39, 0xb1, 0x36, 0x55, 0x2f, 0x7b, 0x79, 0xed, 0x34, 0x2f, 0xe5, 0x3b, 0x73, 0x7d, 0x39, 0x41, |
|
| 240 |
+ 0xcf, 0x00, 0xcd, 0x29, 0xce, 0x38, 0x0b, 0x89, 0x10, 0x8c, 0xe3, 0x90, 0xcd, 0x52, 0x69, 0xd5, |
|
| 241 |
+ 0x3a, 0xc6, 0xe1, 0x86, 0xd7, 0x98, 0x53, 0xb7, 0x2c, 0xf4, 0x72, 0x1d, 0xd9, 0xd0, 0x9c, 0x53, |
|
| 242 |
+ 0x4c, 0x09, 0x65, 0x7c, 0x81, 0x45, 0xf2, 0x8e, 0xe0, 0x24, 0xc5, 0x34, 0xb0, 0xcc, 0x92, 0x3f, |
|
| 243 |
+ 0x53, 0xa5, 0x51, 0xf2, 0x8e, 0x0c, 0xd3, 0xb3, 0x00, 0xb5, 0x00, 0x5e, 0xba, 0xdf, 0x5d, 0xbd, |
|
| 244 |
+ 0xea, 0xe7, 0x6b, 0x59, 0xa0, 0x9a, 0xf8, 0x48, 0x41, 0x5f, 0xc3, 0x43, 0x11, 0xfa, 0x53, 0x82, |
|
| 245 |
+ 0xc3, 0x6c, 0x86, 0xa7, 0x09, 0x4d, 0xa4, 0xc0, 0x92, 0x61, 0xbd, 0x2d, 0x6b, 0x4b, 0x5d, 0xfa, |
|
| 246 |
+ 0xa7, 0x0a, 0xe9, 0x65, 0xb3, 0xd7, 0x0a, 0xb8, 0x64, 0xfa, 0x1c, 0xd0, 0x19, 0x7c, 0x1e, 0x91, |
|
| 247 |
+ 0xb1, 0x3f, 0x9b, 0x4a, 0xbc, 0x3a, 0x37, 0x2c, 0x42, 0xee, 0xcb, 0x70, 0xb2, 0xea, 0x2e, 0x0e, |
|
| 248 |
+ 0xac, 0x6d, 0xd5, 0x5d, 0x5b, 0xb3, 0xbd, 0x12, 0x1d, 0x15, 0x64, 0xd1, 0xec, 0xcb, 0x00, 0x7d, |
|
| 249 |
+ 0x03, 0x8f, 0x4a, 0xbb, 0x39, 0xbd, 0xcf, 0xa7, 0xae, 0x7c, 0x2c, 0x0d, 0x5d, 0xd1, 0xbb, 0x06, |
|
| 250 |
+ 0xf9, 0x4b, 0x99, 0xf8, 0x9c, 0x94, 0x73, 0xad, 0x1d, 0xd5, 0xff, 0xb6, 0x12, 0x35, 0x8c, 0x3a, |
|
| 251 |
+ 0xb0, 0x75, 0xde, 0x73, 0x39, 0xbb, 0x5e, 0xbc, 0x88, 0x22, 0x6e, 0xed, 0xaa, 0x33, 0xf9, 0x58, |
|
| 252 |
+ 0x3a, 0x78, 0x0a, 0xe6, 0xea, 0xb5, 0x22, 0x13, 0x36, 0xce, 0xdd, 0xa1, 0x3b, 0x68, 0x54, 0x50, |
|
| 253 |
+ 0x0d, 0xd6, 0x4f, 0x87, 0xaf, 0x07, 0x0d, 0x03, 0x6d, 0xc2, 0xda, 0xe0, 0xf2, 0x4d, 0xe3, 0xc1, |
|
| 254 |
+ 0x81, 0x03, 0x8d, 0xbb, 0x8f, 0x02, 0x6d, 0xc1, 0xa6, 0xeb, 0x5d, 0xf4, 0x06, 0xa3, 0x51, 0xa3, |
|
| 255 |
+ 0x82, 0x76, 0x00, 0x5e, 0xfd, 0xe0, 0x0e, 0xbc, 0xab, 0xe1, 0xe8, 0xc2, 0x6b, 0x18, 0x07, 0x7f, |
|
| 256 |
+ 0xae, 0xc1, 0x8e, 0xbe, 0xd3, 0x3e, 0x91, 0x7e, 0x32, 0x15, 0xe8, 0x11, 0x80, 0x7a, 0xd7, 0x38, |
|
| 257 |
+ 0xf5, 0x29, 0x51, 0x39, 0x33, 0x3d, 0x53, 0x29, 0xe7, 0x3e, 0x25, 0xa8, 0x07, 0x10, 0x72, 0xe2, |
|
| 258 |
+ 0x4b, 0x12, 0x61, 0x5f, 0xaa, 0xac, 0x6d, 0x3d, 0xdf, 0xb7, 0x8b, 0x0c, 0xdb, 0x65, 0x86, 0xed, |
|
| 259 |
+ 0xcb, 0x32, 0xc3, 0xdd, 0xda, 0xcd, 0x6d, 0xbb, 0xf2, 0xeb, 0x5f, 0x6d, 0xc3, 0x33, 0xf5, 0xbc, |
|
| 260 |
+ 0x17, 0x12, 0x7d, 0x01, 0xe8, 0x2d, 0xe1, 0x29, 0x99, 0xe2, 0x3c, 0xec, 0xf8, 0xe4, 0xf8, 0x18, |
|
| 261 |
+ 0xa7, 0x42, 0xa5, 0x6d, 0xdd, 0xdb, 0x2d, 0x2a, 0xb9, 0xc3, 0xc9, 0xf1, 0xf1, 0xb9, 0x40, 0x36, |
|
| 262 |
+ 0x7c, 0xa2, 0x5f, 0x58, 0xc8, 0x28, 0x4d, 0x24, 0x0e, 0x16, 0x92, 0x08, 0x15, 0xbb, 0x75, 0x6f, |
|
| 263 |
+ 0xaf, 0x28, 0xf5, 0x54, 0xa5, 0x9b, 0x17, 0xd0, 0x29, 0x74, 0x34, 0xff, 0x33, 0xe3, 0x6f, 0x93, |
|
| 264 |
+ 0x34, 0xc6, 0x82, 0x48, 0x9c, 0xf1, 0x64, 0xee, 0x4b, 0xa2, 0x27, 0x6f, 0xa8, 0xc9, 0x9f, 0x15, |
|
| 265 |
+ 0xdc, 0x9b, 0x02, 0x1b, 0x11, 0xe9, 0x16, 0x50, 0xe1, 0xd3, 0x87, 0xf6, 0x3d, 0x3e, 0xea, 0xf2, |
|
| 266 |
+ 0x22, 0x6d, 0x53, 0x55, 0x36, 0x0f, 0xef, 0xda, 0x8c, 0x14, 0x53, 0xb8, 0x3c, 0x03, 0xd0, 0x69, |
|
| 267 |
+ 0xc2, 0x49, 0xa4, 0x72, 0x57, 0xef, 0xd6, 0x97, 0xb7, 0x6d, 0x53, 0x1f, 0xfb, 0xb0, 0xef, 0x99, |
|
| 268 |
+ 0x1a, 0x18, 0x46, 0xe8, 0x09, 0x34, 0x66, 0x82, 0xf0, 0x7f, 0x1d, 0x4b, 0x4d, 0x2d, 0x52, 0xcf, |
|
| 269 |
+ 0xf5, 0x0f, 0x87, 0xf2, 0x18, 0x36, 0xc9, 0x35, 0x09, 0x73, 0xcf, 0x3c, 0x6c, 0x66, 0x17, 0x96, |
|
| 270 |
+ 0xb7, 0xed, 0xea, 0xe0, 0x9a, 0x84, 0xc3, 0xbe, 0x57, 0xcd, 0x4b, 0xc3, 0xa8, 0x1b, 0xdd, 0xbc, |
|
| 271 |
+ 0x6f, 0x55, 0x7e, 0x7f, 0xdf, 0xaa, 0xfc, 0xb2, 0x6c, 0x19, 0x37, 0xcb, 0x96, 0xf1, 0xdb, 0xb2, |
|
| 272 |
+ 0x65, 0xfc, 0xbd, 0x6c, 0x19, 0x3f, 0x7e, 0xfb, 0xff, 0xff, 0xf1, 0xbf, 0xd2, 0xbf, 0xdf, 0x57, |
|
| 273 |
+ 0x82, 0xaa, 0xba, 0xf7, 0x2f, 0xff, 0x09, 0x00, 0x00, 0xff, 0xff, 0xc9, 0x0d, 0x33, 0xad, 0x48, |
|
| 274 |
+ 0x06, 0x00, 0x00, |
|
| 267 | 275 |
} |
| 268 | 276 |
|
| 269 | 277 |
func (m *Options) Marshal() (dAtA []byte, err error) {
|
| ... | ... |
@@ -341,6 +369,42 @@ func (m *Options) MarshalTo(dAtA []byte) (int, error) {
|
| 341 | 341 |
i = encodeVarintRunhcs(dAtA, i, uint64(len(m.GPUVHDPath))) |
| 342 | 342 |
i += copy(dAtA[i:], m.GPUVHDPath) |
| 343 | 343 |
} |
| 344 |
+ if m.ScaleCpuLimitsToSandbox {
|
|
| 345 |
+ dAtA[i] = 0x58 |
|
| 346 |
+ i++ |
|
| 347 |
+ if m.ScaleCpuLimitsToSandbox {
|
|
| 348 |
+ dAtA[i] = 1 |
|
| 349 |
+ } else {
|
|
| 350 |
+ dAtA[i] = 0 |
|
| 351 |
+ } |
|
| 352 |
+ i++ |
|
| 353 |
+ } |
|
| 354 |
+ if m.DefaultContainerScratchSizeInGb != 0 {
|
|
| 355 |
+ dAtA[i] = 0x60 |
|
| 356 |
+ i++ |
|
| 357 |
+ i = encodeVarintRunhcs(dAtA, i, uint64(m.DefaultContainerScratchSizeInGb)) |
|
| 358 |
+ } |
|
| 359 |
+ if m.DefaultVmScratchSizeInGb != 0 {
|
|
| 360 |
+ dAtA[i] = 0x68 |
|
| 361 |
+ i++ |
|
| 362 |
+ i = encodeVarintRunhcs(dAtA, i, uint64(m.DefaultVmScratchSizeInGb)) |
|
| 363 |
+ } |
|
| 364 |
+ if m.ShareScratch {
|
|
| 365 |
+ dAtA[i] = 0x70 |
|
| 366 |
+ i++ |
|
| 367 |
+ if m.ShareScratch {
|
|
| 368 |
+ dAtA[i] = 1 |
|
| 369 |
+ } else {
|
|
| 370 |
+ dAtA[i] = 0 |
|
| 371 |
+ } |
|
| 372 |
+ i++ |
|
| 373 |
+ } |
|
| 374 |
+ if len(m.NCProxyAddr) > 0 {
|
|
| 375 |
+ dAtA[i] = 0x7a |
|
| 376 |
+ i++ |
|
| 377 |
+ i = encodeVarintRunhcs(dAtA, i, uint64(len(m.NCProxyAddr))) |
|
| 378 |
+ i += copy(dAtA[i:], m.NCProxyAddr) |
|
| 379 |
+ } |
|
| 344 | 380 |
if m.XXX_unrecognized != nil {
|
| 345 | 381 |
i += copy(dAtA[i:], m.XXX_unrecognized) |
| 346 | 382 |
} |
| ... | ... |
@@ -468,6 +532,22 @@ func (m *Options) Size() (n int) {
|
| 468 | 468 |
if l > 0 {
|
| 469 | 469 |
n += 1 + l + sovRunhcs(uint64(l)) |
| 470 | 470 |
} |
| 471 |
+ if m.ScaleCpuLimitsToSandbox {
|
|
| 472 |
+ n += 2 |
|
| 473 |
+ } |
|
| 474 |
+ if m.DefaultContainerScratchSizeInGb != 0 {
|
|
| 475 |
+ n += 1 + sovRunhcs(uint64(m.DefaultContainerScratchSizeInGb)) |
|
| 476 |
+ } |
|
| 477 |
+ if m.DefaultVmScratchSizeInGb != 0 {
|
|
| 478 |
+ n += 1 + sovRunhcs(uint64(m.DefaultVmScratchSizeInGb)) |
|
| 479 |
+ } |
|
| 480 |
+ if m.ShareScratch {
|
|
| 481 |
+ n += 2 |
|
| 482 |
+ } |
|
| 483 |
+ l = len(m.NCProxyAddr) |
|
| 484 |
+ if l > 0 {
|
|
| 485 |
+ n += 1 + l + sovRunhcs(uint64(l)) |
|
| 486 |
+ } |
|
| 471 | 487 |
if m.XXX_unrecognized != nil {
|
| 472 | 488 |
n += len(m.XXX_unrecognized) |
| 473 | 489 |
} |
| ... | ... |
@@ -542,6 +622,11 @@ func (this *Options) String() string {
|
| 542 | 542 |
`VmProcessorCount:` + fmt.Sprintf("%v", this.VmProcessorCount) + `,`,
|
| 543 | 543 |
`VmMemorySizeInMb:` + fmt.Sprintf("%v", this.VmMemorySizeInMb) + `,`,
|
| 544 | 544 |
`GPUVHDPath:` + fmt.Sprintf("%v", this.GPUVHDPath) + `,`,
|
| 545 |
+ `ScaleCpuLimitsToSandbox:` + fmt.Sprintf("%v", this.ScaleCpuLimitsToSandbox) + `,`,
|
|
| 546 |
+ `DefaultContainerScratchSizeInGb:` + fmt.Sprintf("%v", this.DefaultContainerScratchSizeInGb) + `,`,
|
|
| 547 |
+ `DefaultVmScratchSizeInGb:` + fmt.Sprintf("%v", this.DefaultVmScratchSizeInGb) + `,`,
|
|
| 548 |
+ `ShareScratch:` + fmt.Sprintf("%v", this.ShareScratch) + `,`,
|
|
| 549 |
+ `NCProxyAddr:` + fmt.Sprintf("%v", this.NCProxyAddr) + `,`,
|
|
| 545 | 550 |
`XXX_unrecognized:` + fmt.Sprintf("%v", this.XXX_unrecognized) + `,`,
|
| 546 | 551 |
`}`, |
| 547 | 552 |
}, "") |
| ... | ... |
@@ -859,6 +944,116 @@ func (m *Options) Unmarshal(dAtA []byte) error {
|
| 859 | 859 |
} |
| 860 | 860 |
m.GPUVHDPath = string(dAtA[iNdEx:postIndex]) |
| 861 | 861 |
iNdEx = postIndex |
| 862 |
+ case 11: |
|
| 863 |
+ if wireType != 0 {
|
|
| 864 |
+ return fmt.Errorf("proto: wrong wireType = %d for field ScaleCpuLimitsToSandbox", wireType)
|
|
| 865 |
+ } |
|
| 866 |
+ var v int |
|
| 867 |
+ for shift := uint(0); ; shift += 7 {
|
|
| 868 |
+ if shift >= 64 {
|
|
| 869 |
+ return ErrIntOverflowRunhcs |
|
| 870 |
+ } |
|
| 871 |
+ if iNdEx >= l {
|
|
| 872 |
+ return io.ErrUnexpectedEOF |
|
| 873 |
+ } |
|
| 874 |
+ b := dAtA[iNdEx] |
|
| 875 |
+ iNdEx++ |
|
| 876 |
+ v |= int(b&0x7F) << shift |
|
| 877 |
+ if b < 0x80 {
|
|
| 878 |
+ break |
|
| 879 |
+ } |
|
| 880 |
+ } |
|
| 881 |
+ m.ScaleCpuLimitsToSandbox = bool(v != 0) |
|
| 882 |
+ case 12: |
|
| 883 |
+ if wireType != 0 {
|
|
| 884 |
+ return fmt.Errorf("proto: wrong wireType = %d for field DefaultContainerScratchSizeInGb", wireType)
|
|
| 885 |
+ } |
|
| 886 |
+ m.DefaultContainerScratchSizeInGb = 0 |
|
| 887 |
+ for shift := uint(0); ; shift += 7 {
|
|
| 888 |
+ if shift >= 64 {
|
|
| 889 |
+ return ErrIntOverflowRunhcs |
|
| 890 |
+ } |
|
| 891 |
+ if iNdEx >= l {
|
|
| 892 |
+ return io.ErrUnexpectedEOF |
|
| 893 |
+ } |
|
| 894 |
+ b := dAtA[iNdEx] |
|
| 895 |
+ iNdEx++ |
|
| 896 |
+ m.DefaultContainerScratchSizeInGb |= int32(b&0x7F) << shift |
|
| 897 |
+ if b < 0x80 {
|
|
| 898 |
+ break |
|
| 899 |
+ } |
|
| 900 |
+ } |
|
| 901 |
+ case 13: |
|
| 902 |
+ if wireType != 0 {
|
|
| 903 |
+ return fmt.Errorf("proto: wrong wireType = %d for field DefaultVmScratchSizeInGb", wireType)
|
|
| 904 |
+ } |
|
| 905 |
+ m.DefaultVmScratchSizeInGb = 0 |
|
| 906 |
+ for shift := uint(0); ; shift += 7 {
|
|
| 907 |
+ if shift >= 64 {
|
|
| 908 |
+ return ErrIntOverflowRunhcs |
|
| 909 |
+ } |
|
| 910 |
+ if iNdEx >= l {
|
|
| 911 |
+ return io.ErrUnexpectedEOF |
|
| 912 |
+ } |
|
| 913 |
+ b := dAtA[iNdEx] |
|
| 914 |
+ iNdEx++ |
|
| 915 |
+ m.DefaultVmScratchSizeInGb |= int32(b&0x7F) << shift |
|
| 916 |
+ if b < 0x80 {
|
|
| 917 |
+ break |
|
| 918 |
+ } |
|
| 919 |
+ } |
|
| 920 |
+ case 14: |
|
| 921 |
+ if wireType != 0 {
|
|
| 922 |
+ return fmt.Errorf("proto: wrong wireType = %d for field ShareScratch", wireType)
|
|
| 923 |
+ } |
|
| 924 |
+ var v int |
|
| 925 |
+ for shift := uint(0); ; shift += 7 {
|
|
| 926 |
+ if shift >= 64 {
|
|
| 927 |
+ return ErrIntOverflowRunhcs |
|
| 928 |
+ } |
|
| 929 |
+ if iNdEx >= l {
|
|
| 930 |
+ return io.ErrUnexpectedEOF |
|
| 931 |
+ } |
|
| 932 |
+ b := dAtA[iNdEx] |
|
| 933 |
+ iNdEx++ |
|
| 934 |
+ v |= int(b&0x7F) << shift |
|
| 935 |
+ if b < 0x80 {
|
|
| 936 |
+ break |
|
| 937 |
+ } |
|
| 938 |
+ } |
|
| 939 |
+ m.ShareScratch = bool(v != 0) |
|
| 940 |
+ case 15: |
|
| 941 |
+ if wireType != 2 {
|
|
| 942 |
+ return fmt.Errorf("proto: wrong wireType = %d for field NCProxyAddr", wireType)
|
|
| 943 |
+ } |
|
| 944 |
+ var stringLen uint64 |
|
| 945 |
+ for shift := uint(0); ; shift += 7 {
|
|
| 946 |
+ if shift >= 64 {
|
|
| 947 |
+ return ErrIntOverflowRunhcs |
|
| 948 |
+ } |
|
| 949 |
+ if iNdEx >= l {
|
|
| 950 |
+ return io.ErrUnexpectedEOF |
|
| 951 |
+ } |
|
| 952 |
+ b := dAtA[iNdEx] |
|
| 953 |
+ iNdEx++ |
|
| 954 |
+ stringLen |= uint64(b&0x7F) << shift |
|
| 955 |
+ if b < 0x80 {
|
|
| 956 |
+ break |
|
| 957 |
+ } |
|
| 958 |
+ } |
|
| 959 |
+ intStringLen := int(stringLen) |
|
| 960 |
+ if intStringLen < 0 {
|
|
| 961 |
+ return ErrInvalidLengthRunhcs |
|
| 962 |
+ } |
|
| 963 |
+ postIndex := iNdEx + intStringLen |
|
| 964 |
+ if postIndex < 0 {
|
|
| 965 |
+ return ErrInvalidLengthRunhcs |
|
| 966 |
+ } |
|
| 967 |
+ if postIndex > l {
|
|
| 968 |
+ return io.ErrUnexpectedEOF |
|
| 969 |
+ } |
|
| 970 |
+ m.NCProxyAddr = string(dAtA[iNdEx:postIndex]) |
|
| 971 |
+ iNdEx = postIndex |
|
| 862 | 972 |
default: |
| 863 | 973 |
iNdEx = preIndex |
| 864 | 974 |
skippy, err := skipRunhcs(dAtA[iNdEx:]) |
| ... | ... |
@@ -62,7 +62,30 @@ message Options {
|
| 62 | 62 |
|
| 63 | 63 |
// GPUVHDPath is the path to the gpu vhd to add to the uvm |
| 64 | 64 |
// when a container requests a gpu |
| 65 |
- string GPUVHDPath = 10; |
|
| 65 |
+ string GPUVHDPath = 10; |
|
| 66 |
+ |
|
| 67 |
+ // scale_cpu_limits_to_sandbox indicates that container CPU limits should |
|
| 68 |
+ // be adjusted to account for the difference in number of cores between the |
|
| 69 |
+ // host and UVM. |
|
| 70 |
+ bool scale_cpu_limits_to_sandbox = 11; |
|
| 71 |
+ |
|
| 72 |
+ // default_container_scratch_size_in_gb is the default scratch size (sandbox.vhdx) |
|
| 73 |
+ // to be used for containers. Every container will get a sandbox of `size_in_gb` assigned |
|
| 74 |
+ // instead of the default of 20GB. |
|
| 75 |
+ int32 default_container_scratch_size_in_gb = 12; |
|
| 76 |
+ |
|
| 77 |
+ // default_vm_scratch_size_in_gb is the default scratch size (sandbox.vhdx) |
|
| 78 |
+ // to be used for the UVM. This only applies to WCOW as LCOW doesn't mount a scratch |
|
| 79 |
+ // specifically for the UVM. |
|
| 80 |
+ int32 default_vm_scratch_size_in_gb = 13; |
|
| 81 |
+ |
|
| 82 |
+ // share_scratch specifies if we'd like to reuse scratch space between multiple containers. |
|
| 83 |
+ // This currently only affects LCOW. The sandbox containers scratch space is re-used for all |
|
| 84 |
+ // subsequent containers launched in the pod. |
|
| 85 |
+ bool share_scratch = 14; |
|
| 86 |
+ //NCProxyAddr is the address of the network configuration proxy service. If omitted |
|
| 87 |
+ // the network is setup locally. |
|
| 88 |
+ string NCProxyAddr = 15; |
|
| 66 | 89 |
} |
| 67 | 90 |
|
| 68 | 91 |
// ProcessDetails contains additional information about a process. This is the additional |
| 69 | 92 |
new file mode 100644 |
| ... | ... |
@@ -0,0 +1,38 @@ |
| 0 |
+package computestorage |
|
| 1 |
+ |
|
| 2 |
+import ( |
|
| 3 |
+ "context" |
|
| 4 |
+ "encoding/json" |
|
| 5 |
+ |
|
| 6 |
+ "github.com/Microsoft/hcsshim/internal/oc" |
|
| 7 |
+ "github.com/pkg/errors" |
|
| 8 |
+ "go.opencensus.io/trace" |
|
| 9 |
+) |
|
| 10 |
+ |
|
| 11 |
+// AttachLayerStorageFilter sets up the layer storage filter on a writable |
|
| 12 |
+// container layer. |
|
| 13 |
+// |
|
| 14 |
+// `layerPath` is a path to a directory the writable layer is mounted. If the |
|
| 15 |
+// path does not end in a `\` the platform will append it automatically. |
|
| 16 |
+// |
|
| 17 |
+// `layerData` is the parent read-only layer data. |
|
| 18 |
+func AttachLayerStorageFilter(ctx context.Context, layerPath string, layerData LayerData) (err error) {
|
|
| 19 |
+ title := "hcsshim.AttachLayerStorageFilter" |
|
| 20 |
+ ctx, span := trace.StartSpan(ctx, title) //nolint:ineffassign,staticcheck |
|
| 21 |
+ defer span.End() |
|
| 22 |
+ defer func() { oc.SetSpanStatus(span, err) }()
|
|
| 23 |
+ span.AddAttributes( |
|
| 24 |
+ trace.StringAttribute("layerPath", layerPath),
|
|
| 25 |
+ ) |
|
| 26 |
+ |
|
| 27 |
+ bytes, err := json.Marshal(layerData) |
|
| 28 |
+ if err != nil {
|
|
| 29 |
+ return err |
|
| 30 |
+ } |
|
| 31 |
+ |
|
| 32 |
+ err = hcsAttachLayerStorageFilter(layerPath, string(bytes)) |
|
| 33 |
+ if err != nil {
|
|
| 34 |
+ return errors.Wrap(err, "failed to attach layer storage filter") |
|
| 35 |
+ } |
|
| 36 |
+ return nil |
|
| 37 |
+} |
| 0 | 38 |
new file mode 100644 |
| ... | ... |
@@ -0,0 +1,26 @@ |
| 0 |
+package computestorage |
|
| 1 |
+ |
|
| 2 |
+import ( |
|
| 3 |
+ "context" |
|
| 4 |
+ |
|
| 5 |
+ "github.com/Microsoft/hcsshim/internal/oc" |
|
| 6 |
+ "github.com/pkg/errors" |
|
| 7 |
+ "go.opencensus.io/trace" |
|
| 8 |
+) |
|
| 9 |
+ |
|
| 10 |
+// DestroyLayer deletes a container layer. |
|
| 11 |
+// |
|
| 12 |
+// `layerPath` is a path to a directory containing the layer to export. |
|
| 13 |
+func DestroyLayer(ctx context.Context, layerPath string) (err error) {
|
|
| 14 |
+ title := "hcsshim.DestroyLayer" |
|
| 15 |
+ ctx, span := trace.StartSpan(ctx, title) //nolint:ineffassign,staticcheck |
|
| 16 |
+ defer span.End() |
|
| 17 |
+ defer func() { oc.SetSpanStatus(span, err) }()
|
|
| 18 |
+ span.AddAttributes(trace.StringAttribute("layerPath", layerPath))
|
|
| 19 |
+ |
|
| 20 |
+ err = hcsDestroyLayer(layerPath) |
|
| 21 |
+ if err != nil {
|
|
| 22 |
+ return errors.Wrap(err, "failed to destroy layer") |
|
| 23 |
+ } |
|
| 24 |
+ return nil |
|
| 25 |
+} |
| 0 | 26 |
new file mode 100644 |
| ... | ... |
@@ -0,0 +1,26 @@ |
| 0 |
+package computestorage |
|
| 1 |
+ |
|
| 2 |
+import ( |
|
| 3 |
+ "context" |
|
| 4 |
+ |
|
| 5 |
+ "github.com/Microsoft/hcsshim/internal/oc" |
|
| 6 |
+ "github.com/pkg/errors" |
|
| 7 |
+ "go.opencensus.io/trace" |
|
| 8 |
+) |
|
| 9 |
+ |
|
| 10 |
+// DetachLayerStorageFilter detaches the layer storage filter on a writable container layer. |
|
| 11 |
+// |
|
| 12 |
+// `layerPath` is a path to a directory containing the layer to export. |
|
| 13 |
+func DetachLayerStorageFilter(ctx context.Context, layerPath string) (err error) {
|
|
| 14 |
+ title := "hcsshim.DetachLayerStorageFilter" |
|
| 15 |
+ ctx, span := trace.StartSpan(ctx, title) //nolint:ineffassign,staticcheck |
|
| 16 |
+ defer span.End() |
|
| 17 |
+ defer func() { oc.SetSpanStatus(span, err) }()
|
|
| 18 |
+ span.AddAttributes(trace.StringAttribute("layerPath", layerPath))
|
|
| 19 |
+ |
|
| 20 |
+ err = hcsDetachLayerStorageFilter(layerPath) |
|
| 21 |
+ if err != nil {
|
|
| 22 |
+ return errors.Wrap(err, "failed to detach layer storage filter") |
|
| 23 |
+ } |
|
| 24 |
+ return nil |
|
| 25 |
+} |
| 0 | 26 |
new file mode 100644 |
| ... | ... |
@@ -0,0 +1,46 @@ |
| 0 |
+package computestorage |
|
| 1 |
+ |
|
| 2 |
+import ( |
|
| 3 |
+ "context" |
|
| 4 |
+ "encoding/json" |
|
| 5 |
+ |
|
| 6 |
+ "github.com/Microsoft/hcsshim/internal/oc" |
|
| 7 |
+ "github.com/pkg/errors" |
|
| 8 |
+ "go.opencensus.io/trace" |
|
| 9 |
+) |
|
| 10 |
+ |
|
| 11 |
+// ExportLayer exports a container layer. |
|
| 12 |
+// |
|
| 13 |
+// `layerPath` is a path to a directory containing the layer to export. |
|
| 14 |
+// |
|
| 15 |
+// `exportFolderPath` is a pre-existing folder to export the layer to. |
|
| 16 |
+// |
|
| 17 |
+// `layerData` is the parent layer data. |
|
| 18 |
+// |
|
| 19 |
+// `options` are the export options applied to the exported layer. |
|
| 20 |
+func ExportLayer(ctx context.Context, layerPath, exportFolderPath string, layerData LayerData, options ExportLayerOptions) (err error) {
|
|
| 21 |
+ title := "hcsshim.ExportLayer" |
|
| 22 |
+ ctx, span := trace.StartSpan(ctx, title) //nolint:ineffassign,staticcheck |
|
| 23 |
+ defer span.End() |
|
| 24 |
+ defer func() { oc.SetSpanStatus(span, err) }()
|
|
| 25 |
+ span.AddAttributes( |
|
| 26 |
+ trace.StringAttribute("layerPath", layerPath),
|
|
| 27 |
+ trace.StringAttribute("exportFolderPath", exportFolderPath),
|
|
| 28 |
+ ) |
|
| 29 |
+ |
|
| 30 |
+ ldbytes, err := json.Marshal(layerData) |
|
| 31 |
+ if err != nil {
|
|
| 32 |
+ return err |
|
| 33 |
+ } |
|
| 34 |
+ |
|
| 35 |
+ obytes, err := json.Marshal(options) |
|
| 36 |
+ if err != nil {
|
|
| 37 |
+ return err |
|
| 38 |
+ } |
|
| 39 |
+ |
|
| 40 |
+ err = hcsExportLayer(layerPath, exportFolderPath, string(ldbytes), string(obytes)) |
|
| 41 |
+ if err != nil {
|
|
| 42 |
+ return errors.Wrap(err, "failed to export layer") |
|
| 43 |
+ } |
|
| 44 |
+ return nil |
|
| 45 |
+} |
| 0 | 46 |
new file mode 100644 |
| ... | ... |
@@ -0,0 +1,26 @@ |
| 0 |
+package computestorage |
|
| 1 |
+ |
|
| 2 |
+import ( |
|
| 3 |
+ "context" |
|
| 4 |
+ |
|
| 5 |
+ "github.com/Microsoft/hcsshim/internal/oc" |
|
| 6 |
+ "github.com/pkg/errors" |
|
| 7 |
+ "go.opencensus.io/trace" |
|
| 8 |
+ "golang.org/x/sys/windows" |
|
| 9 |
+) |
|
| 10 |
+ |
|
| 11 |
+// FormatWritableLayerVhd formats a virtual disk for use as a writable container layer. |
|
| 12 |
+// |
|
| 13 |
+// If the VHD is not mounted it will be temporarily mounted. |
|
| 14 |
+func FormatWritableLayerVhd(ctx context.Context, vhdHandle windows.Handle) (err error) {
|
|
| 15 |
+ title := "hcsshim.FormatWritableLayerVhd" |
|
| 16 |
+ ctx, span := trace.StartSpan(ctx, title) //nolint:ineffassign,staticcheck |
|
| 17 |
+ defer span.End() |
|
| 18 |
+ defer func() { oc.SetSpanStatus(span, err) }()
|
|
| 19 |
+ |
|
| 20 |
+ err = hcsFormatWritableLayerVhd(vhdHandle) |
|
| 21 |
+ if err != nil {
|
|
| 22 |
+ return errors.Wrap(err, "failed to format writable layer vhd") |
|
| 23 |
+ } |
|
| 24 |
+ return nil |
|
| 25 |
+} |
| 0 | 26 |
new file mode 100644 |
| ... | ... |
@@ -0,0 +1,193 @@ |
| 0 |
+package computestorage |
|
| 1 |
+ |
|
| 2 |
+import ( |
|
| 3 |
+ "context" |
|
| 4 |
+ "os" |
|
| 5 |
+ "path/filepath" |
|
| 6 |
+ "syscall" |
|
| 7 |
+ |
|
| 8 |
+ "github.com/Microsoft/go-winio/pkg/security" |
|
| 9 |
+ "github.com/Microsoft/go-winio/vhd" |
|
| 10 |
+ "github.com/pkg/errors" |
|
| 11 |
+ "golang.org/x/sys/windows" |
|
| 12 |
+) |
|
| 13 |
+ |
|
| 14 |
+const defaultVHDXBlockSizeInMB = 1 |
|
| 15 |
+ |
|
| 16 |
+// SetupContainerBaseLayer is a helper to setup a containers scratch. It |
|
| 17 |
+// will create and format the vhdx's inside and the size is configurable with the sizeInGB |
|
| 18 |
+// parameter. |
|
| 19 |
+// |
|
| 20 |
+// `layerPath` is the path to the base container layer on disk. |
|
| 21 |
+// |
|
| 22 |
+// `baseVhdPath` is the path to where the base vhdx for the base layer should be created. |
|
| 23 |
+// |
|
| 24 |
+// `diffVhdPath` is the path where the differencing disk for the base layer should be created. |
|
| 25 |
+// |
|
| 26 |
+// `sizeInGB` is the size in gigabytes to make the base vhdx. |
|
| 27 |
+func SetupContainerBaseLayer(ctx context.Context, layerPath, baseVhdPath, diffVhdPath string, sizeInGB uint64) (err error) {
|
|
| 28 |
+ var ( |
|
| 29 |
+ hivesPath = filepath.Join(layerPath, "Hives") |
|
| 30 |
+ layoutPath = filepath.Join(layerPath, "Layout") |
|
| 31 |
+ ) |
|
| 32 |
+ |
|
| 33 |
+ // We need to remove the hives directory and layout file as `SetupBaseOSLayer` fails if these files |
|
| 34 |
+ // already exist. `SetupBaseOSLayer` will create these files internally. We also remove the base and |
|
| 35 |
+ // differencing disks if they exist in case we're asking for a different size. |
|
| 36 |
+ if _, err := os.Stat(hivesPath); err == nil {
|
|
| 37 |
+ if err := os.RemoveAll(hivesPath); err != nil {
|
|
| 38 |
+ return errors.Wrap(err, "failed to remove prexisting hives directory") |
|
| 39 |
+ } |
|
| 40 |
+ } |
|
| 41 |
+ if _, err := os.Stat(layoutPath); err == nil {
|
|
| 42 |
+ if err := os.RemoveAll(layoutPath); err != nil {
|
|
| 43 |
+ return errors.Wrap(err, "failed to remove prexisting layout file") |
|
| 44 |
+ } |
|
| 45 |
+ } |
|
| 46 |
+ |
|
| 47 |
+ if _, err := os.Stat(baseVhdPath); err == nil {
|
|
| 48 |
+ if err := os.RemoveAll(baseVhdPath); err != nil {
|
|
| 49 |
+ return errors.Wrap(err, "failed to remove base vhdx path") |
|
| 50 |
+ } |
|
| 51 |
+ } |
|
| 52 |
+ if _, err := os.Stat(diffVhdPath); err == nil {
|
|
| 53 |
+ if err := os.RemoveAll(diffVhdPath); err != nil {
|
|
| 54 |
+ return errors.Wrap(err, "failed to remove differencing vhdx") |
|
| 55 |
+ } |
|
| 56 |
+ } |
|
| 57 |
+ |
|
| 58 |
+ createParams := &vhd.CreateVirtualDiskParameters{
|
|
| 59 |
+ Version: 2, |
|
| 60 |
+ Version2: vhd.CreateVersion2{
|
|
| 61 |
+ MaximumSize: sizeInGB * 1024 * 1024 * 1024, |
|
| 62 |
+ BlockSizeInBytes: defaultVHDXBlockSizeInMB * 1024 * 1024, |
|
| 63 |
+ }, |
|
| 64 |
+ } |
|
| 65 |
+ handle, err := vhd.CreateVirtualDisk(baseVhdPath, vhd.VirtualDiskAccessNone, vhd.CreateVirtualDiskFlagNone, createParams) |
|
| 66 |
+ if err != nil {
|
|
| 67 |
+ return errors.Wrap(err, "failed to create vhdx") |
|
| 68 |
+ } |
|
| 69 |
+ |
|
| 70 |
+ defer func() {
|
|
| 71 |
+ if err != nil {
|
|
| 72 |
+ _ = syscall.CloseHandle(handle) |
|
| 73 |
+ os.RemoveAll(baseVhdPath) |
|
| 74 |
+ os.RemoveAll(diffVhdPath) |
|
| 75 |
+ } |
|
| 76 |
+ }() |
|
| 77 |
+ |
|
| 78 |
+ if err = FormatWritableLayerVhd(ctx, windows.Handle(handle)); err != nil {
|
|
| 79 |
+ return err |
|
| 80 |
+ } |
|
| 81 |
+ // Base vhd handle must be closed before calling SetupBaseLayer in case of Container layer |
|
| 82 |
+ if err = syscall.CloseHandle(handle); err != nil {
|
|
| 83 |
+ return errors.Wrap(err, "failed to close vhdx handle") |
|
| 84 |
+ } |
|
| 85 |
+ |
|
| 86 |
+ options := OsLayerOptions{
|
|
| 87 |
+ Type: OsLayerTypeContainer, |
|
| 88 |
+ } |
|
| 89 |
+ |
|
| 90 |
+ // SetupBaseOSLayer expects an empty vhd handle for a container layer and will |
|
| 91 |
+ // error out otherwise. |
|
| 92 |
+ if err = SetupBaseOSLayer(ctx, layerPath, 0, options); err != nil {
|
|
| 93 |
+ return err |
|
| 94 |
+ } |
|
| 95 |
+ // Create the differencing disk that will be what's copied for the final rw layer |
|
| 96 |
+ // for a container. |
|
| 97 |
+ if err = vhd.CreateDiffVhd(diffVhdPath, baseVhdPath, defaultVHDXBlockSizeInMB); err != nil {
|
|
| 98 |
+ return errors.Wrap(err, "failed to create differencing disk") |
|
| 99 |
+ } |
|
| 100 |
+ |
|
| 101 |
+ if err = security.GrantVmGroupAccess(baseVhdPath); err != nil {
|
|
| 102 |
+ return errors.Wrapf(err, "failed to grant vm group access to %s", baseVhdPath) |
|
| 103 |
+ } |
|
| 104 |
+ if err = security.GrantVmGroupAccess(diffVhdPath); err != nil {
|
|
| 105 |
+ return errors.Wrapf(err, "failed to grant vm group access to %s", diffVhdPath) |
|
| 106 |
+ } |
|
| 107 |
+ return nil |
|
| 108 |
+} |
|
| 109 |
+ |
|
| 110 |
+// SetupUtilityVMBaseLayer is a helper to setup a UVMs scratch space. It will create and format |
|
| 111 |
+// the vhdx inside and the size is configurable by the sizeInGB parameter. |
|
| 112 |
+// |
|
| 113 |
+// `uvmPath` is the path to the UtilityVM filesystem. |
|
| 114 |
+// |
|
| 115 |
+// `baseVhdPath` is the path to where the base vhdx for the UVM should be created. |
|
| 116 |
+// |
|
| 117 |
+// `diffVhdPath` is the path where the differencing disk for the UVM should be created. |
|
| 118 |
+// |
|
| 119 |
+// `sizeInGB` specifies the size in gigabytes to make the base vhdx. |
|
| 120 |
+func SetupUtilityVMBaseLayer(ctx context.Context, uvmPath, baseVhdPath, diffVhdPath string, sizeInGB uint64) (err error) {
|
|
| 121 |
+ // Remove the base and differencing disks if they exist in case we're asking for a different size. |
|
| 122 |
+ if _, err := os.Stat(baseVhdPath); err == nil {
|
|
| 123 |
+ if err := os.RemoveAll(baseVhdPath); err != nil {
|
|
| 124 |
+ return errors.Wrap(err, "failed to remove base vhdx") |
|
| 125 |
+ } |
|
| 126 |
+ } |
|
| 127 |
+ if _, err := os.Stat(diffVhdPath); err == nil {
|
|
| 128 |
+ if err := os.RemoveAll(diffVhdPath); err != nil {
|
|
| 129 |
+ return errors.Wrap(err, "failed to remove differencing vhdx") |
|
| 130 |
+ } |
|
| 131 |
+ } |
|
| 132 |
+ |
|
| 133 |
+ // Just create the vhdx for utilityVM layer, no need to format it. |
|
| 134 |
+ createParams := &vhd.CreateVirtualDiskParameters{
|
|
| 135 |
+ Version: 2, |
|
| 136 |
+ Version2: vhd.CreateVersion2{
|
|
| 137 |
+ MaximumSize: sizeInGB * 1024 * 1024 * 1024, |
|
| 138 |
+ BlockSizeInBytes: defaultVHDXBlockSizeInMB * 1024 * 1024, |
|
| 139 |
+ }, |
|
| 140 |
+ } |
|
| 141 |
+ handle, err := vhd.CreateVirtualDisk(baseVhdPath, vhd.VirtualDiskAccessNone, vhd.CreateVirtualDiskFlagNone, createParams) |
|
| 142 |
+ if err != nil {
|
|
| 143 |
+ return errors.Wrap(err, "failed to create vhdx") |
|
| 144 |
+ } |
|
| 145 |
+ |
|
| 146 |
+ defer func() {
|
|
| 147 |
+ if err != nil {
|
|
| 148 |
+ _ = syscall.CloseHandle(handle) |
|
| 149 |
+ os.RemoveAll(baseVhdPath) |
|
| 150 |
+ os.RemoveAll(diffVhdPath) |
|
| 151 |
+ } |
|
| 152 |
+ }() |
|
| 153 |
+ |
|
| 154 |
+ // If it is a UtilityVM layer then the base vhdx must be attached when calling |
|
| 155 |
+ // `SetupBaseOSLayer` |
|
| 156 |
+ attachParams := &vhd.AttachVirtualDiskParameters{
|
|
| 157 |
+ Version: 2, |
|
| 158 |
+ } |
|
| 159 |
+ if err := vhd.AttachVirtualDisk(handle, vhd.AttachVirtualDiskFlagNone, attachParams); err != nil {
|
|
| 160 |
+ return errors.Wrapf(err, "failed to attach virtual disk") |
|
| 161 |
+ } |
|
| 162 |
+ |
|
| 163 |
+ options := OsLayerOptions{
|
|
| 164 |
+ Type: OsLayerTypeVM, |
|
| 165 |
+ } |
|
| 166 |
+ if err := SetupBaseOSLayer(ctx, uvmPath, windows.Handle(handle), options); err != nil {
|
|
| 167 |
+ return err |
|
| 168 |
+ } |
|
| 169 |
+ |
|
| 170 |
+ // Detach and close the handle after setting up the layer as we don't need the handle |
|
| 171 |
+ // for anything else and we no longer need to be attached either. |
|
| 172 |
+ if err = vhd.DetachVirtualDisk(handle); err != nil {
|
|
| 173 |
+ return errors.Wrap(err, "failed to detach vhdx") |
|
| 174 |
+ } |
|
| 175 |
+ if err = syscall.CloseHandle(handle); err != nil {
|
|
| 176 |
+ return errors.Wrap(err, "failed to close vhdx handle") |
|
| 177 |
+ } |
|
| 178 |
+ |
|
| 179 |
+ // Create the differencing disk that will be what's copied for the final rw layer |
|
| 180 |
+ // for a container. |
|
| 181 |
+ if err = vhd.CreateDiffVhd(diffVhdPath, baseVhdPath, defaultVHDXBlockSizeInMB); err != nil {
|
|
| 182 |
+ return errors.Wrap(err, "failed to create differencing disk") |
|
| 183 |
+ } |
|
| 184 |
+ |
|
| 185 |
+ if err := security.GrantVmGroupAccess(baseVhdPath); err != nil {
|
|
| 186 |
+ return errors.Wrapf(err, "failed to grant vm group access to %s", baseVhdPath) |
|
| 187 |
+ } |
|
| 188 |
+ if err := security.GrantVmGroupAccess(diffVhdPath); err != nil {
|
|
| 189 |
+ return errors.Wrapf(err, "failed to grant vm group access to %s", diffVhdPath) |
|
| 190 |
+ } |
|
| 191 |
+ return nil |
|
| 192 |
+} |
| 0 | 193 |
new file mode 100644 |
| ... | ... |
@@ -0,0 +1,41 @@ |
| 0 |
+package computestorage |
|
| 1 |
+ |
|
| 2 |
+import ( |
|
| 3 |
+ "context" |
|
| 4 |
+ "encoding/json" |
|
| 5 |
+ |
|
| 6 |
+ "github.com/Microsoft/hcsshim/internal/oc" |
|
| 7 |
+ "github.com/pkg/errors" |
|
| 8 |
+ "go.opencensus.io/trace" |
|
| 9 |
+) |
|
| 10 |
+ |
|
| 11 |
+// ImportLayer imports a container layer. |
|
| 12 |
+// |
|
| 13 |
+// `layerPath` is a path to a directory to import the layer to. If the directory |
|
| 14 |
+// does not exist it will be automatically created. |
|
| 15 |
+// |
|
| 16 |
+// `sourceFolderpath` is a pre-existing folder that contains the layer to |
|
| 17 |
+// import. |
|
| 18 |
+// |
|
| 19 |
+// `layerData` is the parent layer data. |
|
| 20 |
+func ImportLayer(ctx context.Context, layerPath, sourceFolderPath string, layerData LayerData) (err error) {
|
|
| 21 |
+ title := "hcsshim.ImportLayer" |
|
| 22 |
+ ctx, span := trace.StartSpan(ctx, title) //nolint:ineffassign,staticcheck |
|
| 23 |
+ defer span.End() |
|
| 24 |
+ defer func() { oc.SetSpanStatus(span, err) }()
|
|
| 25 |
+ span.AddAttributes( |
|
| 26 |
+ trace.StringAttribute("layerPath", layerPath),
|
|
| 27 |
+ trace.StringAttribute("sourceFolderPath", sourceFolderPath),
|
|
| 28 |
+ ) |
|
| 29 |
+ |
|
| 30 |
+ bytes, err := json.Marshal(layerData) |
|
| 31 |
+ if err != nil {
|
|
| 32 |
+ return err |
|
| 33 |
+ } |
|
| 34 |
+ |
|
| 35 |
+ err = hcsImportLayer(layerPath, sourceFolderPath, string(bytes)) |
|
| 36 |
+ if err != nil {
|
|
| 37 |
+ return errors.Wrap(err, "failed to import layer") |
|
| 38 |
+ } |
|
| 39 |
+ return nil |
|
| 40 |
+} |
| 0 | 41 |
new file mode 100644 |
| ... | ... |
@@ -0,0 +1,38 @@ |
| 0 |
+package computestorage |
|
| 1 |
+ |
|
| 2 |
+import ( |
|
| 3 |
+ "context" |
|
| 4 |
+ "encoding/json" |
|
| 5 |
+ |
|
| 6 |
+ "github.com/Microsoft/hcsshim/internal/oc" |
|
| 7 |
+ "github.com/pkg/errors" |
|
| 8 |
+ "go.opencensus.io/trace" |
|
| 9 |
+) |
|
| 10 |
+ |
|
| 11 |
+// InitializeWritableLayer initializes a writable layer for a container. |
|
| 12 |
+// |
|
| 13 |
+// `layerPath` is a path to a directory the layer is mounted. If the |
|
| 14 |
+// path does not end in a `\` the platform will append it automatically. |
|
| 15 |
+// |
|
| 16 |
+// `layerData` is the parent read-only layer data. |
|
| 17 |
+func InitializeWritableLayer(ctx context.Context, layerPath string, layerData LayerData) (err error) {
|
|
| 18 |
+ title := "hcsshim.InitializeWritableLayer" |
|
| 19 |
+ ctx, span := trace.StartSpan(ctx, title) //nolint:ineffassign,staticcheck |
|
| 20 |
+ defer span.End() |
|
| 21 |
+ defer func() { oc.SetSpanStatus(span, err) }()
|
|
| 22 |
+ span.AddAttributes( |
|
| 23 |
+ trace.StringAttribute("layerPath", layerPath),
|
|
| 24 |
+ ) |
|
| 25 |
+ |
|
| 26 |
+ bytes, err := json.Marshal(layerData) |
|
| 27 |
+ if err != nil {
|
|
| 28 |
+ return err |
|
| 29 |
+ } |
|
| 30 |
+ |
|
| 31 |
+ // Options are not used in the platform as of RS5 |
|
| 32 |
+ err = hcsInitializeWritableLayer(layerPath, string(bytes), "") |
|
| 33 |
+ if err != nil {
|
|
| 34 |
+ return errors.Wrap(err, "failed to intitialize container layer") |
|
| 35 |
+ } |
|
| 36 |
+ return nil |
|
| 37 |
+} |
| 0 | 38 |
new file mode 100644 |
| ... | ... |
@@ -0,0 +1,27 @@ |
| 0 |
+package computestorage |
|
| 1 |
+ |
|
| 2 |
+import ( |
|
| 3 |
+ "context" |
|
| 4 |
+ |
|
| 5 |
+ "github.com/Microsoft/hcsshim/internal/interop" |
|
| 6 |
+ "github.com/Microsoft/hcsshim/internal/oc" |
|
| 7 |
+ "github.com/pkg/errors" |
|
| 8 |
+ "go.opencensus.io/trace" |
|
| 9 |
+ "golang.org/x/sys/windows" |
|
| 10 |
+) |
|
| 11 |
+ |
|
| 12 |
+// GetLayerVhdMountPath returns the volume path for a virtual disk of a writable container layer. |
|
| 13 |
+func GetLayerVhdMountPath(ctx context.Context, vhdHandle windows.Handle) (path string, err error) {
|
|
| 14 |
+ title := "hcsshim.GetLayerVhdMountPath" |
|
| 15 |
+ ctx, span := trace.StartSpan(ctx, title) //nolint:ineffassign,staticcheck |
|
| 16 |
+ defer span.End() |
|
| 17 |
+ defer func() { oc.SetSpanStatus(span, err) }()
|
|
| 18 |
+ |
|
| 19 |
+ var mountPath *uint16 |
|
| 20 |
+ err = hcsGetLayerVhdMountPath(vhdHandle, &mountPath) |
|
| 21 |
+ if err != nil {
|
|
| 22 |
+ return "", errors.Wrap(err, "failed to get vhd mount path") |
|
| 23 |
+ } |
|
| 24 |
+ path = interop.ConvertAndFreeCoTaskMemString(mountPath) |
|
| 25 |
+ return path, nil |
|
| 26 |
+} |
| 0 | 27 |
new file mode 100644 |
| ... | ... |
@@ -0,0 +1,74 @@ |
| 0 |
+package computestorage |
|
| 1 |
+ |
|
| 2 |
+import ( |
|
| 3 |
+ "context" |
|
| 4 |
+ "encoding/json" |
|
| 5 |
+ |
|
| 6 |
+ "github.com/Microsoft/hcsshim/internal/oc" |
|
| 7 |
+ "github.com/Microsoft/hcsshim/osversion" |
|
| 8 |
+ "github.com/pkg/errors" |
|
| 9 |
+ "go.opencensus.io/trace" |
|
| 10 |
+ "golang.org/x/sys/windows" |
|
| 11 |
+) |
|
| 12 |
+ |
|
| 13 |
+// SetupBaseOSLayer sets up a layer that contains a base OS for a container. |
|
| 14 |
+// |
|
| 15 |
+// `layerPath` is a path to a directory containing the layer. |
|
| 16 |
+// |
|
| 17 |
+// `vhdHandle` is an empty file handle of `options.Type == OsLayerTypeContainer` |
|
| 18 |
+// or else it is a file handle to the 'SystemTemplateBase.vhdx' if `options.Type |
|
| 19 |
+// == OsLayerTypeVm`. |
|
| 20 |
+// |
|
| 21 |
+// `options` are the options applied while processing the layer. |
|
| 22 |
+func SetupBaseOSLayer(ctx context.Context, layerPath string, vhdHandle windows.Handle, options OsLayerOptions) (err error) {
|
|
| 23 |
+ title := "hcsshim.SetupBaseOSLayer" |
|
| 24 |
+ ctx, span := trace.StartSpan(ctx, title) //nolint:ineffassign,staticcheck |
|
| 25 |
+ defer span.End() |
|
| 26 |
+ defer func() { oc.SetSpanStatus(span, err) }()
|
|
| 27 |
+ span.AddAttributes( |
|
| 28 |
+ trace.StringAttribute("layerPath", layerPath),
|
|
| 29 |
+ ) |
|
| 30 |
+ |
|
| 31 |
+ bytes, err := json.Marshal(options) |
|
| 32 |
+ if err != nil {
|
|
| 33 |
+ return err |
|
| 34 |
+ } |
|
| 35 |
+ |
|
| 36 |
+ err = hcsSetupBaseOSLayer(layerPath, vhdHandle, string(bytes)) |
|
| 37 |
+ if err != nil {
|
|
| 38 |
+ return errors.Wrap(err, "failed to setup base OS layer") |
|
| 39 |
+ } |
|
| 40 |
+ return nil |
|
| 41 |
+} |
|
| 42 |
+ |
|
| 43 |
+// SetupBaseOSVolume sets up a volume that contains a base OS for a container. |
|
| 44 |
+// |
|
| 45 |
+// `layerPath` is a path to a directory containing the layer. |
|
| 46 |
+// |
|
| 47 |
+// `volumePath` is the path to the volume to be used for setup. |
|
| 48 |
+// |
|
| 49 |
+// `options` are the options applied while processing the layer. |
|
| 50 |
+func SetupBaseOSVolume(ctx context.Context, layerPath, volumePath string, options OsLayerOptions) (err error) {
|
|
| 51 |
+ if osversion.Get().Build < 19645 {
|
|
| 52 |
+ return errors.New("SetupBaseOSVolume is not present on builds older than 19645")
|
|
| 53 |
+ } |
|
| 54 |
+ title := "hcsshim.SetupBaseOSVolume" |
|
| 55 |
+ ctx, span := trace.StartSpan(ctx, title) //nolint:ineffassign,staticcheck |
|
| 56 |
+ defer span.End() |
|
| 57 |
+ defer func() { oc.SetSpanStatus(span, err) }()
|
|
| 58 |
+ span.AddAttributes( |
|
| 59 |
+ trace.StringAttribute("layerPath", layerPath),
|
|
| 60 |
+ trace.StringAttribute("volumePath", volumePath),
|
|
| 61 |
+ ) |
|
| 62 |
+ |
|
| 63 |
+ bytes, err := json.Marshal(options) |
|
| 64 |
+ if err != nil {
|
|
| 65 |
+ return err |
|
| 66 |
+ } |
|
| 67 |
+ |
|
| 68 |
+ err = hcsSetupBaseOSVolume(layerPath, volumePath, string(bytes)) |
|
| 69 |
+ if err != nil {
|
|
| 70 |
+ return errors.Wrap(err, "failed to setup base OS layer") |
|
| 71 |
+ } |
|
| 72 |
+ return nil |
|
| 73 |
+} |
| 0 | 74 |
new file mode 100644 |
| ... | ... |
@@ -0,0 +1,50 @@ |
| 0 |
+// Package computestorage is a wrapper around the HCS storage APIs. These are new storage APIs introduced |
|
| 1 |
+// separate from the original graphdriver calls intended to give more freedom around creating |
|
| 2 |
+// and managing container layers and scratch spaces. |
|
| 3 |
+package computestorage |
|
| 4 |
+ |
|
| 5 |
+import ( |
|
| 6 |
+ hcsschema "github.com/Microsoft/hcsshim/internal/schema2" |
|
| 7 |
+) |
|
| 8 |
+ |
|
| 9 |
+//go:generate go run ../mksyscall_windows.go -output zsyscall_windows.go storage.go |
|
| 10 |
+ |
|
| 11 |
+//sys hcsImportLayer(layerPath string, sourceFolderPath string, layerData string) (hr error) = computestorage.HcsImportLayer? |
|
| 12 |
+//sys hcsExportLayer(layerPath string, exportFolderPath string, layerData string, options string) (hr error) = computestorage.HcsExportLayer? |
|
| 13 |
+//sys hcsDestroyLayer(layerPath string) (hr error) = computestorage.HcsDestoryLayer? |
|
| 14 |
+//sys hcsSetupBaseOSLayer(layerPath string, handle windows.Handle, options string) (hr error) = computestorage.HcsSetupBaseOSLayer? |
|
| 15 |
+//sys hcsInitializeWritableLayer(writableLayerPath string, layerData string, options string) (hr error) = computestorage.HcsInitializeWritableLayer? |
|
| 16 |
+//sys hcsAttachLayerStorageFilter(layerPath string, layerData string) (hr error) = computestorage.HcsAttachLayerStorageFilter? |
|
| 17 |
+//sys hcsDetachLayerStorageFilter(layerPath string) (hr error) = computestorage.HcsDetachLayerStorageFilter? |
|
| 18 |
+//sys hcsFormatWritableLayerVhd(handle windows.Handle) (hr error) = computestorage.HcsFormatWritableLayerVhd? |
|
| 19 |
+//sys hcsGetLayerVhdMountPath(vhdHandle windows.Handle, mountPath **uint16) (hr error) = computestorage.HcsGetLayerVhdMountPath? |
|
| 20 |
+//sys hcsSetupBaseOSVolume(layerPath string, volumePath string, options string) (hr error) = computestorage.HcsSetupBaseOSVolume? |
|
| 21 |
+ |
|
| 22 |
+// LayerData is the data used to describe parent layer information. |
|
| 23 |
+type LayerData struct {
|
|
| 24 |
+ SchemaVersion hcsschema.Version `json:"SchemaVersion,omitempty"` |
|
| 25 |
+ Layers []hcsschema.Layer `json:"Layers,omitempty"` |
|
| 26 |
+} |
|
| 27 |
+ |
|
| 28 |
+// ExportLayerOptions are the set of options that are used with the `computestorage.HcsExportLayer` syscall. |
|
| 29 |
+type ExportLayerOptions struct {
|
|
| 30 |
+ IsWritableLayer bool `json:"IsWritableLayer,omitempty"` |
|
| 31 |
+} |
|
| 32 |
+ |
|
| 33 |
+// OsLayerType is the type of layer being operated on. |
|
| 34 |
+type OsLayerType string |
|
| 35 |
+ |
|
| 36 |
+const ( |
|
| 37 |
+ // OsLayerTypeContainer is a container layer. |
|
| 38 |
+ OsLayerTypeContainer OsLayerType = "Container" |
|
| 39 |
+ // OsLayerTypeVM is a virtual machine layer. |
|
| 40 |
+ OsLayerTypeVM OsLayerType = "Vm" |
|
| 41 |
+) |
|
| 42 |
+ |
|
| 43 |
+// OsLayerOptions are the set of options that are used with the `SetupBaseOSLayer` and |
|
| 44 |
+// `SetupBaseOSVolume` calls. |
|
| 45 |
+type OsLayerOptions struct {
|
|
| 46 |
+ Type OsLayerType `json:"Type,omitempty"` |
|
| 47 |
+ DisableCiCacheOptimization bool `json:"DisableCiCacheOptimization,omitempty"` |
|
| 48 |
+ SkipUpdateBcdForBoot bool `json:"SkipUpdateBcdForBoot,omitempty"` |
|
| 49 |
+} |
| 0 | 50 |
new file mode 100644 |
| ... | ... |
@@ -0,0 +1,319 @@ |
| 0 |
+// Code generated mksyscall_windows.exe DO NOT EDIT |
|
| 1 |
+ |
|
| 2 |
+package computestorage |
|
| 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 |
+ modcomputestorage = windows.NewLazySystemDLL("computestorage.dll")
|
|
| 40 |
+ |
|
| 41 |
+ procHcsImportLayer = modcomputestorage.NewProc("HcsImportLayer")
|
|
| 42 |
+ procHcsExportLayer = modcomputestorage.NewProc("HcsExportLayer")
|
|
| 43 |
+ procHcsDestoryLayer = modcomputestorage.NewProc("HcsDestoryLayer")
|
|
| 44 |
+ procHcsSetupBaseOSLayer = modcomputestorage.NewProc("HcsSetupBaseOSLayer")
|
|
| 45 |
+ procHcsInitializeWritableLayer = modcomputestorage.NewProc("HcsInitializeWritableLayer")
|
|
| 46 |
+ procHcsAttachLayerStorageFilter = modcomputestorage.NewProc("HcsAttachLayerStorageFilter")
|
|
| 47 |
+ procHcsDetachLayerStorageFilter = modcomputestorage.NewProc("HcsDetachLayerStorageFilter")
|
|
| 48 |
+ procHcsFormatWritableLayerVhd = modcomputestorage.NewProc("HcsFormatWritableLayerVhd")
|
|
| 49 |
+ procHcsGetLayerVhdMountPath = modcomputestorage.NewProc("HcsGetLayerVhdMountPath")
|
|
| 50 |
+ procHcsSetupBaseOSVolume = modcomputestorage.NewProc("HcsSetupBaseOSVolume")
|
|
| 51 |
+) |
|
| 52 |
+ |
|
| 53 |
+func hcsImportLayer(layerPath string, sourceFolderPath string, layerData string) (hr error) {
|
|
| 54 |
+ var _p0 *uint16 |
|
| 55 |
+ _p0, hr = syscall.UTF16PtrFromString(layerPath) |
|
| 56 |
+ if hr != nil {
|
|
| 57 |
+ return |
|
| 58 |
+ } |
|
| 59 |
+ var _p1 *uint16 |
|
| 60 |
+ _p1, hr = syscall.UTF16PtrFromString(sourceFolderPath) |
|
| 61 |
+ if hr != nil {
|
|
| 62 |
+ return |
|
| 63 |
+ } |
|
| 64 |
+ var _p2 *uint16 |
|
| 65 |
+ _p2, hr = syscall.UTF16PtrFromString(layerData) |
|
| 66 |
+ if hr != nil {
|
|
| 67 |
+ return |
|
| 68 |
+ } |
|
| 69 |
+ return _hcsImportLayer(_p0, _p1, _p2) |
|
| 70 |
+} |
|
| 71 |
+ |
|
| 72 |
+func _hcsImportLayer(layerPath *uint16, sourceFolderPath *uint16, layerData *uint16) (hr error) {
|
|
| 73 |
+ if hr = procHcsImportLayer.Find(); hr != nil {
|
|
| 74 |
+ return |
|
| 75 |
+ } |
|
| 76 |
+ r0, _, _ := syscall.Syscall(procHcsImportLayer.Addr(), 3, uintptr(unsafe.Pointer(layerPath)), uintptr(unsafe.Pointer(sourceFolderPath)), uintptr(unsafe.Pointer(layerData))) |
|
| 77 |
+ if int32(r0) < 0 {
|
|
| 78 |
+ if r0&0x1fff0000 == 0x00070000 {
|
|
| 79 |
+ r0 &= 0xffff |
|
| 80 |
+ } |
|
| 81 |
+ hr = syscall.Errno(r0) |
|
| 82 |
+ } |
|
| 83 |
+ return |
|
| 84 |
+} |
|
| 85 |
+ |
|
| 86 |
+func hcsExportLayer(layerPath string, exportFolderPath string, layerData string, options string) (hr error) {
|
|
| 87 |
+ var _p0 *uint16 |
|
| 88 |
+ _p0, hr = syscall.UTF16PtrFromString(layerPath) |
|
| 89 |
+ if hr != nil {
|
|
| 90 |
+ return |
|
| 91 |
+ } |
|
| 92 |
+ var _p1 *uint16 |
|
| 93 |
+ _p1, hr = syscall.UTF16PtrFromString(exportFolderPath) |
|
| 94 |
+ if hr != nil {
|
|
| 95 |
+ return |
|
| 96 |
+ } |
|
| 97 |
+ var _p2 *uint16 |
|
| 98 |
+ _p2, hr = syscall.UTF16PtrFromString(layerData) |
|
| 99 |
+ if hr != nil {
|
|
| 100 |
+ return |
|
| 101 |
+ } |
|
| 102 |
+ var _p3 *uint16 |
|
| 103 |
+ _p3, hr = syscall.UTF16PtrFromString(options) |
|
| 104 |
+ if hr != nil {
|
|
| 105 |
+ return |
|
| 106 |
+ } |
|
| 107 |
+ return _hcsExportLayer(_p0, _p1, _p2, _p3) |
|
| 108 |
+} |
|
| 109 |
+ |
|
| 110 |
+func _hcsExportLayer(layerPath *uint16, exportFolderPath *uint16, layerData *uint16, options *uint16) (hr error) {
|
|
| 111 |
+ if hr = procHcsExportLayer.Find(); hr != nil {
|
|
| 112 |
+ return |
|
| 113 |
+ } |
|
| 114 |
+ r0, _, _ := syscall.Syscall6(procHcsExportLayer.Addr(), 4, uintptr(unsafe.Pointer(layerPath)), uintptr(unsafe.Pointer(exportFolderPath)), uintptr(unsafe.Pointer(layerData)), uintptr(unsafe.Pointer(options)), 0, 0) |
|
| 115 |
+ if int32(r0) < 0 {
|
|
| 116 |
+ if r0&0x1fff0000 == 0x00070000 {
|
|
| 117 |
+ r0 &= 0xffff |
|
| 118 |
+ } |
|
| 119 |
+ hr = syscall.Errno(r0) |
|
| 120 |
+ } |
|
| 121 |
+ return |
|
| 122 |
+} |
|
| 123 |
+ |
|
| 124 |
+func hcsDestroyLayer(layerPath string) (hr error) {
|
|
| 125 |
+ var _p0 *uint16 |
|
| 126 |
+ _p0, hr = syscall.UTF16PtrFromString(layerPath) |
|
| 127 |
+ if hr != nil {
|
|
| 128 |
+ return |
|
| 129 |
+ } |
|
| 130 |
+ return _hcsDestroyLayer(_p0) |
|
| 131 |
+} |
|
| 132 |
+ |
|
| 133 |
+func _hcsDestroyLayer(layerPath *uint16) (hr error) {
|
|
| 134 |
+ if hr = procHcsDestoryLayer.Find(); hr != nil {
|
|
| 135 |
+ return |
|
| 136 |
+ } |
|
| 137 |
+ r0, _, _ := syscall.Syscall(procHcsDestoryLayer.Addr(), 1, uintptr(unsafe.Pointer(layerPath)), 0, 0) |
|
| 138 |
+ if int32(r0) < 0 {
|
|
| 139 |
+ if r0&0x1fff0000 == 0x00070000 {
|
|
| 140 |
+ r0 &= 0xffff |
|
| 141 |
+ } |
|
| 142 |
+ hr = syscall.Errno(r0) |
|
| 143 |
+ } |
|
| 144 |
+ return |
|
| 145 |
+} |
|
| 146 |
+ |
|
| 147 |
+func hcsSetupBaseOSLayer(layerPath string, handle windows.Handle, options string) (hr error) {
|
|
| 148 |
+ var _p0 *uint16 |
|
| 149 |
+ _p0, hr = syscall.UTF16PtrFromString(layerPath) |
|
| 150 |
+ if hr != nil {
|
|
| 151 |
+ return |
|
| 152 |
+ } |
|
| 153 |
+ var _p1 *uint16 |
|
| 154 |
+ _p1, hr = syscall.UTF16PtrFromString(options) |
|
| 155 |
+ if hr != nil {
|
|
| 156 |
+ return |
|
| 157 |
+ } |
|
| 158 |
+ return _hcsSetupBaseOSLayer(_p0, handle, _p1) |
|
| 159 |
+} |
|
| 160 |
+ |
|
| 161 |
+func _hcsSetupBaseOSLayer(layerPath *uint16, handle windows.Handle, options *uint16) (hr error) {
|
|
| 162 |
+ if hr = procHcsSetupBaseOSLayer.Find(); hr != nil {
|
|
| 163 |
+ return |
|
| 164 |
+ } |
|
| 165 |
+ r0, _, _ := syscall.Syscall(procHcsSetupBaseOSLayer.Addr(), 3, uintptr(unsafe.Pointer(layerPath)), uintptr(handle), uintptr(unsafe.Pointer(options))) |
|
| 166 |
+ if int32(r0) < 0 {
|
|
| 167 |
+ if r0&0x1fff0000 == 0x00070000 {
|
|
| 168 |
+ r0 &= 0xffff |
|
| 169 |
+ } |
|
| 170 |
+ hr = syscall.Errno(r0) |
|
| 171 |
+ } |
|
| 172 |
+ return |
|
| 173 |
+} |
|
| 174 |
+ |
|
| 175 |
+func hcsInitializeWritableLayer(writableLayerPath string, layerData string, options string) (hr error) {
|
|
| 176 |
+ var _p0 *uint16 |
|
| 177 |
+ _p0, hr = syscall.UTF16PtrFromString(writableLayerPath) |
|
| 178 |
+ if hr != nil {
|
|
| 179 |
+ return |
|
| 180 |
+ } |
|
| 181 |
+ var _p1 *uint16 |
|
| 182 |
+ _p1, hr = syscall.UTF16PtrFromString(layerData) |
|
| 183 |
+ if hr != nil {
|
|
| 184 |
+ return |
|
| 185 |
+ } |
|
| 186 |
+ var _p2 *uint16 |
|
| 187 |
+ _p2, hr = syscall.UTF16PtrFromString(options) |
|
| 188 |
+ if hr != nil {
|
|
| 189 |
+ return |
|
| 190 |
+ } |
|
| 191 |
+ return _hcsInitializeWritableLayer(_p0, _p1, _p2) |
|
| 192 |
+} |
|
| 193 |
+ |
|
| 194 |
+func _hcsInitializeWritableLayer(writableLayerPath *uint16, layerData *uint16, options *uint16) (hr error) {
|
|
| 195 |
+ if hr = procHcsInitializeWritableLayer.Find(); hr != nil {
|
|
| 196 |
+ return |
|
| 197 |
+ } |
|
| 198 |
+ r0, _, _ := syscall.Syscall(procHcsInitializeWritableLayer.Addr(), 3, uintptr(unsafe.Pointer(writableLayerPath)), uintptr(unsafe.Pointer(layerData)), uintptr(unsafe.Pointer(options))) |
|
| 199 |
+ if int32(r0) < 0 {
|
|
| 200 |
+ if r0&0x1fff0000 == 0x00070000 {
|
|
| 201 |
+ r0 &= 0xffff |
|
| 202 |
+ } |
|
| 203 |
+ hr = syscall.Errno(r0) |
|
| 204 |
+ } |
|
| 205 |
+ return |
|
| 206 |
+} |
|
| 207 |
+ |
|
| 208 |
+func hcsAttachLayerStorageFilter(layerPath string, layerData string) (hr error) {
|
|
| 209 |
+ var _p0 *uint16 |
|
| 210 |
+ _p0, hr = syscall.UTF16PtrFromString(layerPath) |
|
| 211 |
+ if hr != nil {
|
|
| 212 |
+ return |
|
| 213 |
+ } |
|
| 214 |
+ var _p1 *uint16 |
|
| 215 |
+ _p1, hr = syscall.UTF16PtrFromString(layerData) |
|
| 216 |
+ if hr != nil {
|
|
| 217 |
+ return |
|
| 218 |
+ } |
|
| 219 |
+ return _hcsAttachLayerStorageFilter(_p0, _p1) |
|
| 220 |
+} |
|
| 221 |
+ |
|
| 222 |
+func _hcsAttachLayerStorageFilter(layerPath *uint16, layerData *uint16) (hr error) {
|
|
| 223 |
+ if hr = procHcsAttachLayerStorageFilter.Find(); hr != nil {
|
|
| 224 |
+ return |
|
| 225 |
+ } |
|
| 226 |
+ r0, _, _ := syscall.Syscall(procHcsAttachLayerStorageFilter.Addr(), 2, uintptr(unsafe.Pointer(layerPath)), uintptr(unsafe.Pointer(layerData)), 0) |
|
| 227 |
+ if int32(r0) < 0 {
|
|
| 228 |
+ if r0&0x1fff0000 == 0x00070000 {
|
|
| 229 |
+ r0 &= 0xffff |
|
| 230 |
+ } |
|
| 231 |
+ hr = syscall.Errno(r0) |
|
| 232 |
+ } |
|
| 233 |
+ return |
|
| 234 |
+} |
|
| 235 |
+ |
|
| 236 |
+func hcsDetachLayerStorageFilter(layerPath string) (hr error) {
|
|
| 237 |
+ var _p0 *uint16 |
|
| 238 |
+ _p0, hr = syscall.UTF16PtrFromString(layerPath) |
|
| 239 |
+ if hr != nil {
|
|
| 240 |
+ return |
|
| 241 |
+ } |
|
| 242 |
+ return _hcsDetachLayerStorageFilter(_p0) |
|
| 243 |
+} |
|
| 244 |
+ |
|
| 245 |
+func _hcsDetachLayerStorageFilter(layerPath *uint16) (hr error) {
|
|
| 246 |
+ if hr = procHcsDetachLayerStorageFilter.Find(); hr != nil {
|
|
| 247 |
+ return |
|
| 248 |
+ } |
|
| 249 |
+ r0, _, _ := syscall.Syscall(procHcsDetachLayerStorageFilter.Addr(), 1, uintptr(unsafe.Pointer(layerPath)), 0, 0) |
|
| 250 |
+ if int32(r0) < 0 {
|
|
| 251 |
+ if r0&0x1fff0000 == 0x00070000 {
|
|
| 252 |
+ r0 &= 0xffff |
|
| 253 |
+ } |
|
| 254 |
+ hr = syscall.Errno(r0) |
|
| 255 |
+ } |
|
| 256 |
+ return |
|
| 257 |
+} |
|
| 258 |
+ |
|
| 259 |
+func hcsFormatWritableLayerVhd(handle windows.Handle) (hr error) {
|
|
| 260 |
+ if hr = procHcsFormatWritableLayerVhd.Find(); hr != nil {
|
|
| 261 |
+ return |
|
| 262 |
+ } |
|
| 263 |
+ r0, _, _ := syscall.Syscall(procHcsFormatWritableLayerVhd.Addr(), 1, uintptr(handle), 0, 0) |
|
| 264 |
+ if int32(r0) < 0 {
|
|
| 265 |
+ if r0&0x1fff0000 == 0x00070000 {
|
|
| 266 |
+ r0 &= 0xffff |
|
| 267 |
+ } |
|
| 268 |
+ hr = syscall.Errno(r0) |
|
| 269 |
+ } |
|
| 270 |
+ return |
|
| 271 |
+} |
|
| 272 |
+ |
|
| 273 |
+func hcsGetLayerVhdMountPath(vhdHandle windows.Handle, mountPath **uint16) (hr error) {
|
|
| 274 |
+ if hr = procHcsGetLayerVhdMountPath.Find(); hr != nil {
|
|
| 275 |
+ return |
|
| 276 |
+ } |
|
| 277 |
+ r0, _, _ := syscall.Syscall(procHcsGetLayerVhdMountPath.Addr(), 2, uintptr(vhdHandle), uintptr(unsafe.Pointer(mountPath)), 0) |
|
| 278 |
+ if int32(r0) < 0 {
|
|
| 279 |
+ if r0&0x1fff0000 == 0x00070000 {
|
|
| 280 |
+ r0 &= 0xffff |
|
| 281 |
+ } |
|
| 282 |
+ hr = syscall.Errno(r0) |
|
| 283 |
+ } |
|
| 284 |
+ return |
|
| 285 |
+} |
|
| 286 |
+ |
|
| 287 |
+func hcsSetupBaseOSVolume(layerPath string, volumePath string, options string) (hr error) {
|
|
| 288 |
+ var _p0 *uint16 |
|
| 289 |
+ _p0, hr = syscall.UTF16PtrFromString(layerPath) |
|
| 290 |
+ if hr != nil {
|
|
| 291 |
+ return |
|
| 292 |
+ } |
|
| 293 |
+ var _p1 *uint16 |
|
| 294 |
+ _p1, hr = syscall.UTF16PtrFromString(volumePath) |
|
| 295 |
+ if hr != nil {
|
|
| 296 |
+ return |
|
| 297 |
+ } |
|
| 298 |
+ var _p2 *uint16 |
|
| 299 |
+ _p2, hr = syscall.UTF16PtrFromString(options) |
|
| 300 |
+ if hr != nil {
|
|
| 301 |
+ return |
|
| 302 |
+ } |
|
| 303 |
+ return _hcsSetupBaseOSVolume(_p0, _p1, _p2) |
|
| 304 |
+} |
|
| 305 |
+ |
|
| 306 |
+func _hcsSetupBaseOSVolume(layerPath *uint16, volumePath *uint16, options *uint16) (hr error) {
|
|
| 307 |
+ if hr = procHcsSetupBaseOSVolume.Find(); hr != nil {
|
|
| 308 |
+ return |
|
| 309 |
+ } |
|
| 310 |
+ r0, _, _ := syscall.Syscall(procHcsSetupBaseOSVolume.Addr(), 3, uintptr(unsafe.Pointer(layerPath)), uintptr(unsafe.Pointer(volumePath)), uintptr(unsafe.Pointer(options))) |
|
| 311 |
+ if int32(r0) < 0 {
|
|
| 312 |
+ if r0&0x1fff0000 == 0x00070000 {
|
|
| 313 |
+ r0 &= 0xffff |
|
| 314 |
+ } |
|
| 315 |
+ hr = syscall.Errno(r0) |
|
| 316 |
+ } |
|
| 317 |
+ return |
|
| 318 |
+} |
| ... | ... |
@@ -83,7 +83,6 @@ type NetworkNotFoundError = hns.NetworkNotFoundError |
| 83 | 83 |
type ProcessError struct {
|
| 84 | 84 |
Process *process |
| 85 | 85 |
Operation string |
| 86 |
- ExtraInfo string |
|
| 87 | 86 |
Err error |
| 88 | 87 |
Events []hcs.ErrorEvent |
| 89 | 88 |
} |
| ... | ... |
@@ -92,7 +91,6 @@ type ProcessError struct {
|
| 92 | 92 |
type ContainerError struct {
|
| 93 | 93 |
Container *container |
| 94 | 94 |
Operation string |
| 95 |
- ExtraInfo string |
|
| 96 | 95 |
Err error |
| 97 | 96 |
Events []hcs.ErrorEvent |
| 98 | 97 |
} |
| ... | ... |
@@ -125,22 +123,9 @@ func (e *ContainerError) Error() string {
|
| 125 | 125 |
s += "\n" + ev.String() |
| 126 | 126 |
} |
| 127 | 127 |
|
| 128 |
- if e.ExtraInfo != "" {
|
|
| 129 |
- s += " extra info: " + e.ExtraInfo |
|
| 130 |
- } |
|
| 131 |
- |
|
| 132 | 128 |
return s |
| 133 | 129 |
} |
| 134 | 130 |
|
| 135 |
-func makeContainerError(container *container, operation string, extraInfo string, err error) error {
|
|
| 136 |
- // Don't double wrap errors |
|
| 137 |
- if _, ok := err.(*ContainerError); ok {
|
|
| 138 |
- return err |
|
| 139 |
- } |
|
| 140 |
- containerError := &ContainerError{Container: container, Operation: operation, ExtraInfo: extraInfo, Err: err}
|
|
| 141 |
- return containerError |
|
| 142 |
-} |
|
| 143 |
- |
|
| 144 | 131 |
func (e *ProcessError) Error() string {
|
| 145 | 132 |
if e == nil {
|
| 146 | 133 |
return "<nil>" |
| ... | ... |
@@ -171,15 +156,6 @@ func (e *ProcessError) Error() string {
|
| 171 | 171 |
return s |
| 172 | 172 |
} |
| 173 | 173 |
|
| 174 |
-func makeProcessError(process *process, operation string, extraInfo string, err error) error {
|
|
| 175 |
- // Don't double wrap errors |
|
| 176 |
- if _, ok := err.(*ProcessError); ok {
|
|
| 177 |
- return err |
|
| 178 |
- } |
|
| 179 |
- processError := &ProcessError{Process: process, Operation: operation, ExtraInfo: extraInfo, Err: err}
|
|
| 180 |
- return processError |
|
| 181 |
-} |
|
| 182 |
- |
|
| 183 | 174 |
// IsNotExist checks if an error is caused by the Container or Process not existing. |
| 184 | 175 |
// Note: Currently, ErrElementNotFound can mean that a Process has either |
| 185 | 176 |
// already exited, or does not exist. Both IsAlreadyStopped and IsNotExist |
| ... | ... |
@@ -230,6 +206,18 @@ func IsNotSupported(err error) bool {
|
| 230 | 230 |
return hcs.IsNotSupported(getInnerError(err)) |
| 231 | 231 |
} |
| 232 | 232 |
|
| 233 |
+// IsOperationInvalidState returns true when err is caused by |
|
| 234 |
+// `ErrVmcomputeOperationInvalidState`. |
|
| 235 |
+func IsOperationInvalidState(err error) bool {
|
|
| 236 |
+ return hcs.IsOperationInvalidState(getInnerError(err)) |
|
| 237 |
+} |
|
| 238 |
+ |
|
| 239 |
+// IsAccessIsDenied returns true when err is caused by |
|
| 240 |
+// `ErrVmcomputeOperationAccessIsDenied`. |
|
| 241 |
+func IsAccessIsDenied(err error) bool {
|
|
| 242 |
+ return hcs.IsAccessIsDenied(getInnerError(err)) |
|
| 243 |
+} |
|
| 244 |
+ |
|
| 233 | 245 |
func getInnerError(err error) error {
|
| 234 | 246 |
switch pe := err.(type) {
|
| 235 | 247 |
case nil: |
| ... | ... |
@@ -244,7 +232,7 @@ func getInnerError(err error) error {
|
| 244 | 244 |
|
| 245 | 245 |
func convertSystemError(err error, c *container) error {
|
| 246 | 246 |
if serr, ok := err.(*hcs.SystemError); ok {
|
| 247 |
- return &ContainerError{Container: c, Operation: serr.Op, ExtraInfo: serr.Extra, Err: serr.Err, Events: serr.Events}
|
|
| 247 |
+ return &ContainerError{Container: c, Operation: serr.Op, Err: serr.Err, Events: serr.Events}
|
|
| 248 | 248 |
} |
| 249 | 249 |
return err |
| 250 | 250 |
} |
| ... | ... |
@@ -514,6 +514,45 @@ func (w *Writer) lookup(name string, mustExist bool) (*inode, *inode, string, er |
| 514 | 514 |
return dir, child, childname, nil |
| 515 | 515 |
} |
| 516 | 516 |
|
| 517 |
+// CreateWithParents adds a file to the file system creating the parent directories in the path if |
|
| 518 |
+// they don't exist (like `mkdir -p`). These non existing parent directories are created |
|
| 519 |
+// with the same permissions as that of it's parent directory. It is expected that the a |
|
| 520 |
+// call to make these parent directories will be made at a later point with the correct |
|
| 521 |
+// permissions, at that time the permissions of these directories will be updated. |
|
| 522 |
+func (w *Writer) CreateWithParents(name string, f *File) error {
|
|
| 523 |
+ // go through the directories in the path one by one and create the |
|
| 524 |
+ // parent directories if they don't exist. |
|
| 525 |
+ cleanname := path.Clean("/" + name)[1:]
|
|
| 526 |
+ parentDirs, _ := path.Split(cleanname) |
|
| 527 |
+ currentPath := "" |
|
| 528 |
+ root := w.root() |
|
| 529 |
+ dirname := "" |
|
| 530 |
+ for parentDirs != "" {
|
|
| 531 |
+ dirname, parentDirs = splitFirst(parentDirs) |
|
| 532 |
+ currentPath += "/" + dirname |
|
| 533 |
+ if _, ok := root.Children[dirname]; !ok {
|
|
| 534 |
+ f := &File{
|
|
| 535 |
+ Mode: root.Mode, |
|
| 536 |
+ Atime: time.Now(), |
|
| 537 |
+ Mtime: time.Now(), |
|
| 538 |
+ Ctime: time.Now(), |
|
| 539 |
+ Crtime: time.Now(), |
|
| 540 |
+ Size: 0, |
|
| 541 |
+ Uid: root.Uid, |
|
| 542 |
+ Gid: root.Gid, |
|
| 543 |
+ Devmajor: root.Devmajor, |
|
| 544 |
+ Devminor: root.Devminor, |
|
| 545 |
+ Xattrs: make(map[string][]byte), |
|
| 546 |
+ } |
|
| 547 |
+ if err := w.Create(currentPath, f); err != nil {
|
|
| 548 |
+ return fmt.Errorf("failed while creating parent directories: %w", err)
|
|
| 549 |
+ } |
|
| 550 |
+ } |
|
| 551 |
+ root = root.Children[dirname] |
|
| 552 |
+ } |
|
| 553 |
+ return w.Create(name, f) |
|
| 554 |
+} |
|
| 555 |
+ |
|
| 517 | 556 |
// Create adds a file to the file system. |
| 518 | 557 |
func (w *Writer) Create(name string, f *File) error {
|
| 519 | 558 |
if err := w.finishInode(); err != nil {
|
| ... | ... |
@@ -693,7 +732,7 @@ func (w *Writer) seekBlock(block uint32) {
|
| 693 | 693 |
func (w *Writer) nextBlock() {
|
| 694 | 694 |
if w.pos%blockSize != 0 {
|
| 695 | 695 |
// Simplify callers; w.err is updated on failure. |
| 696 |
- w.zero(blockSize - w.pos%blockSize) |
|
| 696 |
+ _, _ = w.zero(blockSize - w.pos%blockSize) |
|
| 697 | 697 |
} |
| 698 | 698 |
} |
| 699 | 699 |
|
| ... | ... |
@@ -743,7 +782,7 @@ func (w *Writer) writeExtents(inode *inode) error {
|
| 743 | 743 |
extents [4]format.ExtentLeafNode |
| 744 | 744 |
} |
| 745 | 745 |
fillExtents(&root.hdr, root.extents[:extents], startBlock, 0, blocks) |
| 746 |
- binary.Write(&b, binary.LittleEndian, root) |
|
| 746 |
+ _ = binary.Write(&b, binary.LittleEndian, root) |
|
| 747 | 747 |
} else if extents <= 4*extentsPerBlock {
|
| 748 | 748 |
const extentsPerBlock = blockSize/extentNodeSize - 1 |
| 749 | 749 |
extentBlocks := extents/extentsPerBlock + 1 |
| ... | ... |
@@ -778,12 +817,12 @@ func (w *Writer) writeExtents(inode *inode) error {
|
| 778 | 778 |
|
| 779 | 779 |
offset := i * extentsPerBlock * maxBlocksPerExtent |
| 780 | 780 |
fillExtents(&node.hdr, node.extents[:extentsInBlock], startBlock+offset, offset, blocks) |
| 781 |
- binary.Write(&b2, binary.LittleEndian, node) |
|
| 781 |
+ _ = binary.Write(&b2, binary.LittleEndian, node) |
|
| 782 | 782 |
if _, err := w.write(b2.Next(blockSize)); err != nil {
|
| 783 | 783 |
return err |
| 784 | 784 |
} |
| 785 | 785 |
} |
| 786 |
- binary.Write(&b, binary.LittleEndian, root) |
|
| 786 |
+ _ = binary.Write(&b, binary.LittleEndian, root) |
|
| 787 | 787 |
} else {
|
| 788 | 788 |
panic("file too big")
|
| 789 | 789 |
} |
| ... | ... |
@@ -924,7 +963,13 @@ func (w *Writer) writeDirectory(dir, parent *inode) error {
|
| 924 | 924 |
children = append(children, name) |
| 925 | 925 |
} |
| 926 | 926 |
sort.Slice(children, func(i, j int) bool {
|
| 927 |
- return dir.Children[children[i]].Number < dir.Children[children[j]].Number |
|
| 927 |
+ left_num := dir.Children[children[i]].Number |
|
| 928 |
+ right_num := dir.Children[children[j]].Number |
|
| 929 |
+ |
|
| 930 |
+ if left_num == right_num {
|
|
| 931 |
+ return children[i] < children[j] |
|
| 932 |
+ } |
|
| 933 |
+ return left_num < right_num |
|
| 928 | 934 |
}) |
| 929 | 935 |
|
| 930 | 936 |
for _, name := range children {
|
| ... | ... |
@@ -945,7 +990,24 @@ func (w *Writer) writeDirectoryRecursive(dir, parent *inode) error {
|
| 945 | 945 |
if err := w.writeDirectory(dir, parent); err != nil {
|
| 946 | 946 |
return err |
| 947 | 947 |
} |
| 948 |
- for _, child := range dir.Children {
|
|
| 948 |
+ |
|
| 949 |
+ // Follow e2fsck's convention and sort the children by inode number. |
|
| 950 |
+ var children []string |
|
| 951 |
+ for name := range dir.Children {
|
|
| 952 |
+ children = append(children, name) |
|
| 953 |
+ } |
|
| 954 |
+ sort.Slice(children, func(i, j int) bool {
|
|
| 955 |
+ left_num := dir.Children[children[i]].Number |
|
| 956 |
+ right_num := dir.Children[children[j]].Number |
|
| 957 |
+ |
|
| 958 |
+ if left_num == right_num {
|
|
| 959 |
+ return children[i] < children[j] |
|
| 960 |
+ } |
|
| 961 |
+ return left_num < right_num |
|
| 962 |
+ }) |
|
| 963 |
+ |
|
| 964 |
+ for _, name := range children {
|
|
| 965 |
+ child := dir.Children[name] |
|
| 949 | 966 |
if child.IsDir() {
|
| 950 | 967 |
if err := w.writeDirectoryRecursive(child, dir); err != nil {
|
| 951 | 968 |
return err |
| ... | ... |
@@ -998,12 +1060,12 @@ func (w *Writer) writeInodeTable(tableSize uint32) error {
|
| 998 | 998 |
binary.LittleEndian.PutUint32(binode.Block[4:], dev) |
| 999 | 999 |
} |
| 1000 | 1000 |
|
| 1001 |
- binary.Write(&b, binary.LittleEndian, binode) |
|
| 1001 |
+ _ = binary.Write(&b, binary.LittleEndian, binode) |
|
| 1002 | 1002 |
b.Truncate(inodeUsedSize) |
| 1003 | 1003 |
n, _ := b.Write(inode.XattrInline) |
| 1004 |
- io.CopyN(&b, zero, int64(inodeExtraSize-n)) |
|
| 1004 |
+ _, _ = io.CopyN(&b, zero, int64(inodeExtraSize-n)) |
|
| 1005 | 1005 |
} else {
|
| 1006 |
- io.CopyN(&b, zero, inodeSize) |
|
| 1006 |
+ _, _ = io.CopyN(&b, zero, inodeSize) |
|
| 1007 | 1007 |
} |
| 1008 | 1008 |
if _, err := w.write(b.Next(inodeSize)); err != nil {
|
| 1009 | 1009 |
return err |
| ... | ... |
@@ -1136,7 +1198,7 @@ func (w *Writer) Close() error {
|
| 1136 | 1136 |
diskSize = minSize |
| 1137 | 1137 |
} |
| 1138 | 1138 |
|
| 1139 |
- usedGdBlocks := (groups-1)/groupDescriptorSize + 1 |
|
| 1139 |
+ usedGdBlocks := (groups-1)/groupsPerDescriptorBlock + 1 |
|
| 1140 | 1140 |
if usedGdBlocks > w.gdBlocks {
|
| 1141 | 1141 |
return exceededMaxSizeError{w.maxDiskSize}
|
| 1142 | 1142 |
} |
| ... | ... |
@@ -1253,7 +1315,7 @@ func (w *Writer) Close() error {
|
| 1253 | 1253 |
if w.supportInlineData {
|
| 1254 | 1254 |
sb.FeatureIncompat |= format.IncompatInlineData |
| 1255 | 1255 |
} |
| 1256 |
- binary.Write(b, binary.LittleEndian, sb) |
|
| 1256 |
+ _ = binary.Write(b, binary.LittleEndian, sb) |
|
| 1257 | 1257 |
w.seekBlock(0) |
| 1258 | 1258 |
if _, err := w.write(blk[:]); err != nil {
|
| 1259 | 1259 |
return err |
| ... | ... |
@@ -5,10 +5,12 @@ import ( |
| 5 | 5 |
"bufio" |
| 6 | 6 |
"encoding/binary" |
| 7 | 7 |
"io" |
| 8 |
+ "os" |
|
| 8 | 9 |
"path" |
| 9 | 10 |
"strings" |
| 10 | 11 |
|
| 11 | 12 |
"github.com/Microsoft/hcsshim/ext4/internal/compactext4" |
| 13 |
+ "github.com/Microsoft/hcsshim/ext4/internal/format" |
|
| 12 | 14 |
) |
| 13 | 15 |
|
| 14 | 16 |
type params struct {
|
| ... | ... |
@@ -146,7 +148,7 @@ func Convert(r io.Reader, w io.ReadWriteSeeker, options ...Option) error {
|
| 146 | 146 |
} |
| 147 | 147 |
f.Mode &= ^compactext4.TypeMask |
| 148 | 148 |
f.Mode |= typ |
| 149 |
- err = fs.Create(hdr.Name, f) |
|
| 149 |
+ err = fs.CreateWithParents(hdr.Name, f) |
|
| 150 | 150 |
if err != nil {
|
| 151 | 151 |
return err |
| 152 | 152 |
} |
| ... | ... |
@@ -172,3 +174,36 @@ func Convert(r io.Reader, w io.ReadWriteSeeker, options ...Option) error {
|
| 172 | 172 |
} |
| 173 | 173 |
return nil |
| 174 | 174 |
} |
| 175 |
+ |
|
| 176 |
+// ReadExt4SuperBlock reads and returns ext4 super block from VHD |
|
| 177 |
+// |
|
| 178 |
+// The layout on disk is as follows: |
|
| 179 |
+// | Group 0 padding | - 1024 bytes |
|
| 180 |
+// | ext4 SuperBlock | - 1 block |
|
| 181 |
+// | Group Descriptors | - many blocks |
|
| 182 |
+// | Reserved GDT Blocks | - many blocks |
|
| 183 |
+// | Data Block Bitmap | - 1 block |
|
| 184 |
+// | inode Bitmap | - 1 block |
|
| 185 |
+// | inode Table | - many blocks |
|
| 186 |
+// | Data Blocks | - many blocks |
|
| 187 |
+// |
|
| 188 |
+// More details can be found here https://ext4.wiki.kernel.org/index.php/Ext4_Disk_Layout |
|
| 189 |
+// |
|
| 190 |
+// Our goal is to skip the Group 0 padding, read and return the ext4 SuperBlock |
|
| 191 |
+func ReadExt4SuperBlock(vhdPath string) (*format.SuperBlock, error) {
|
|
| 192 |
+ vhd, err := os.OpenFile(vhdPath, os.O_RDONLY, 0) |
|
| 193 |
+ if err != nil {
|
|
| 194 |
+ return nil, err |
|
| 195 |
+ } |
|
| 196 |
+ defer vhd.Close() |
|
| 197 |
+ |
|
| 198 |
+ // Skip padding at the start |
|
| 199 |
+ if _, err := vhd.Seek(1024, io.SeekStart); err != nil {
|
|
| 200 |
+ return nil, err |
|
| 201 |
+ } |
|
| 202 |
+ var sb format.SuperBlock |
|
| 203 |
+ if err := binary.Read(vhd, binary.LittleEndian, &sb); err != nil {
|
|
| 204 |
+ return nil, err |
|
| 205 |
+ } |
|
| 206 |
+ return &sb, nil |
|
| 207 |
+} |
| ... | ... |
@@ -3,33 +3,20 @@ module github.com/Microsoft/hcsshim |
| 3 | 3 |
go 1.13 |
| 4 | 4 |
|
| 5 | 5 |
require ( |
| 6 |
- github.com/Microsoft/go-winio v0.4.15-0.20200908182639-5b44b70ab3ab |
|
| 7 |
- github.com/containerd/cgroups v0.0.0-20200531161412-0dbf7f05ba59 |
|
| 8 |
- github.com/containerd/console v0.0.0-20180822173158-c12b1e7919c1 |
|
| 9 |
- github.com/containerd/containerd v1.3.2 |
|
| 10 |
- github.com/containerd/continuity v0.0.0-20190426062206-aaeac12a7ffc // indirect |
|
| 11 |
- github.com/containerd/fifo v0.0.0-20190226154929-a9fb20d87448 // indirect |
|
| 12 |
- github.com/containerd/go-runc v0.0.0-20180907222934-5a6d9f37cfa3 |
|
| 13 |
- github.com/containerd/ttrpc v0.0.0-20190828154514-0e0f228740de |
|
| 14 |
- github.com/containerd/typeurl v0.0.0-20180627222232-a93fcdb778cd |
|
| 15 |
- github.com/gogo/protobuf v1.3.1 |
|
| 16 |
- github.com/golang/protobuf v1.3.2 // indirect |
|
| 17 |
- github.com/kr/pretty v0.1.0 // indirect |
|
| 18 |
- github.com/opencontainers/go-digest v0.0.0-20180430190053-c9281466c8b2 // indirect |
|
| 19 |
- github.com/opencontainers/runc v0.0.0-20190115041553-12f6a991201f // indirect |
|
| 20 |
- github.com/opencontainers/runtime-spec v1.0.2 |
|
| 6 |
+ github.com/Microsoft/go-winio v0.4.17-0.20210211115548-6eac466e5fa3 |
|
| 7 |
+ github.com/containerd/cgroups v0.0.0-20210114181951-8a68de567b68 |
|
| 8 |
+ github.com/containerd/console v1.0.1 |
|
| 9 |
+ github.com/containerd/containerd v1.5.0-beta.4 |
|
| 10 |
+ github.com/containerd/go-runc v0.0.0-20201020171139-16b287bc67d0 |
|
| 11 |
+ github.com/containerd/ttrpc v1.0.2 |
|
| 12 |
+ github.com/containerd/typeurl v1.0.1 |
|
| 13 |
+ github.com/gogo/protobuf v1.3.2 |
|
| 14 |
+ github.com/opencontainers/runtime-spec v1.0.3-0.20200929063507-e6143ca7d51d |
|
| 21 | 15 |
github.com/pkg/errors v0.9.1 |
| 22 |
- github.com/prometheus/procfs v0.0.0-20180125133057-cb4147076ac7 // indirect |
|
| 23 |
- github.com/sirupsen/logrus v1.4.2 |
|
| 24 |
- github.com/stretchr/testify v1.4.0 // indirect |
|
| 16 |
+ github.com/sirupsen/logrus v1.7.0 |
|
| 25 | 17 |
github.com/urfave/cli v1.22.2 |
| 26 |
- go.opencensus.io v0.22.0 |
|
| 27 |
- golang.org/x/net v0.0.0-20191004110552-13f9640d40b9 // indirect |
|
| 28 |
- golang.org/x/sync v0.0.0-20190423024810-112230192c58 |
|
| 29 |
- golang.org/x/sys v0.0.0-20200120151820-655fe14d7479 |
|
| 30 |
- google.golang.org/genproto v0.0.0-20190502173448-54afdca5d873 // indirect |
|
| 31 |
- google.golang.org/grpc v1.23.1 |
|
| 32 |
- gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127 // indirect |
|
| 33 |
- gopkg.in/yaml.v2 v2.2.8 // indirect |
|
| 34 |
- gotest.tools v2.2.0+incompatible // indirect |
|
| 18 |
+ go.opencensus.io v0.22.3 |
|
| 19 |
+ golang.org/x/sync v0.0.0-20201207232520-09787c993a3a |
|
| 20 |
+ golang.org/x/sys v0.0.0-20210324051608-47abb6519492 |
|
| 21 |
+ google.golang.org/grpc v1.33.2 |
|
| 35 | 22 |
) |
| ... | ... |
@@ -40,6 +40,9 @@ func HNSListEndpointRequest() ([]HNSEndpoint, error) {
|
| 40 | 40 |
// HotAttachEndpoint makes a HCS Call to attach the endpoint to the container |
| 41 | 41 |
func HotAttachEndpoint(containerID string, endpointID string) error {
|
| 42 | 42 |
endpoint, err := GetHNSEndpointByID(endpointID) |
| 43 |
+ if err != nil {
|
|
| 44 |
+ return err |
|
| 45 |
+ } |
|
| 43 | 46 |
isAttached, err := endpoint.IsAttached(containerID) |
| 44 | 47 |
if isAttached {
|
| 45 | 48 |
return err |
| ... | ... |
@@ -50,6 +53,9 @@ func HotAttachEndpoint(containerID string, endpointID string) error {
|
| 50 | 50 |
// HotDetachEndpoint makes a HCS Call to detach the endpoint from the container |
| 51 | 51 |
func HotDetachEndpoint(containerID string, endpointID string) error {
|
| 52 | 52 |
endpoint, err := GetHNSEndpointByID(endpointID) |
| 53 |
+ if err != nil {
|
|
| 54 |
+ return err |
|
| 55 |
+ } |
|
| 53 | 56 |
isAttached, err := endpoint.IsAttached(containerID) |
| 54 | 57 |
if !isAttached {
|
| 55 | 58 |
return err |
| ... | ... |
@@ -106,6 +106,7 @@ func newSystemChannels() notificationChannels {
|
| 106 | 106 |
hcsNotificationSystemStartCompleted, |
| 107 | 107 |
hcsNotificationSystemPauseCompleted, |
| 108 | 108 |
hcsNotificationSystemResumeCompleted, |
| 109 |
+ hcsNotificationSystemSaveCompleted, |
|
| 109 | 110 |
} {
|
| 110 | 111 |
channels[notif] = make(notificationChannel, 1) |
| 111 | 112 |
} |
| ... | ... |
@@ -171,7 +171,6 @@ type SystemError struct {
|
| 171 | 171 |
ID string |
| 172 | 172 |
Op string |
| 173 | 173 |
Err error |
| 174 |
- Extra string |
|
| 175 | 174 |
Events []ErrorEvent |
| 176 | 175 |
} |
| 177 | 176 |
|
| ... | ... |
@@ -182,9 +181,6 @@ func (e *SystemError) Error() string {
|
| 182 | 182 |
for _, ev := range e.Events {
|
| 183 | 183 |
s += "\n" + ev.String() |
| 184 | 184 |
} |
| 185 |
- if e.Extra != "" {
|
|
| 186 |
- s += "\n(extra info: " + e.Extra + ")" |
|
| 187 |
- } |
|
| 188 | 185 |
return s |
| 189 | 186 |
} |
| 190 | 187 |
|
| ... | ... |
@@ -198,7 +194,7 @@ func (e *SystemError) Timeout() bool {
|
| 198 | 198 |
return ok && err.Timeout() |
| 199 | 199 |
} |
| 200 | 200 |
|
| 201 |
-func makeSystemError(system *System, op string, extra string, err error, events []ErrorEvent) error {
|
|
| 201 |
+func makeSystemError(system *System, op string, err error, events []ErrorEvent) error {
|
|
| 202 | 202 |
// Don't double wrap errors |
| 203 | 203 |
if _, ok := err.(*SystemError); ok {
|
| 204 | 204 |
return err |
| ... | ... |
@@ -206,7 +202,6 @@ func makeSystemError(system *System, op string, extra string, err error, events |
| 206 | 206 |
return &SystemError{
|
| 207 | 207 |
ID: system.ID(), |
| 208 | 208 |
Op: op, |
| 209 |
- Extra: extra, |
|
| 210 | 209 |
Err: err, |
| 211 | 210 |
Events: events, |
| 212 | 211 |
} |
| ... | ... |
@@ -312,6 +307,13 @@ func IsOperationInvalidState(err error) bool {
|
| 312 | 312 |
return err == ErrVmcomputeOperationInvalidState |
| 313 | 313 |
} |
| 314 | 314 |
|
| 315 |
+// IsAccessIsDenied returns true when err is caused by |
|
| 316 |
+// `ErrVmcomputeOperationAccessIsDenied`. |
|
| 317 |
+func IsAccessIsDenied(err error) bool {
|
|
| 318 |
+ err = getInnerError(err) |
|
| 319 |
+ return err == ErrVmcomputeOperationAccessIsDenied |
|
| 320 |
+} |
|
| 321 |
+ |
|
| 315 | 322 |
func getInnerError(err error) error {
|
| 316 | 323 |
switch pe := err.(type) {
|
| 317 | 324 |
case nil: |
| ... | ... |
@@ -325,12 +327,3 @@ func getInnerError(err error) error {
|
| 325 | 325 |
} |
| 326 | 326 |
return err |
| 327 | 327 |
} |
| 328 |
- |
|
| 329 |
-func getOperationLogResult(err error) (string, error) {
|
|
| 330 |
- switch err {
|
|
| 331 |
- case nil: |
|
| 332 |
- return "Success", nil |
|
| 333 |
- default: |
|
| 334 |
- return "Error", err |
|
| 335 |
- } |
|
| 336 |
-} |
| ... | ... |
@@ -64,11 +64,7 @@ type processStatus struct {
|
| 64 | 64 |
LastWaitResult int32 |
| 65 | 65 |
} |
| 66 | 66 |
|
| 67 |
-const ( |
|
| 68 |
- stdIn string = "StdIn" |
|
| 69 |
- stdOut string = "StdOut" |
|
| 70 |
- stdErr string = "StdErr" |
|
| 71 |
-) |
|
| 67 |
+const stdIn string = "StdIn" |
|
| 72 | 68 |
|
| 73 | 69 |
const ( |
| 74 | 70 |
modifyConsoleSize string = "ConsoleSize" |
| ... | ... |
@@ -176,8 +172,10 @@ func (process *Process) waitBackground() {
|
| 176 | 176 |
trace.Int64Attribute("pid", int64(process.processID)))
|
| 177 | 177 |
|
| 178 | 178 |
var ( |
| 179 |
- err error |
|
| 180 |
- exitCode = -1 |
|
| 179 |
+ err error |
|
| 180 |
+ exitCode = -1 |
|
| 181 |
+ propertiesJSON string |
|
| 182 |
+ resultJSON string |
|
| 181 | 183 |
) |
| 182 | 184 |
|
| 183 | 185 |
err = waitForNotification(ctx, process.callbackNumber, hcsNotificationProcessExited, nil) |
| ... | ... |
@@ -190,15 +188,15 @@ func (process *Process) waitBackground() {
|
| 190 | 190 |
|
| 191 | 191 |
// Make sure we didnt race with Close() here |
| 192 | 192 |
if process.handle != 0 {
|
| 193 |
- propertiesJSON, resultJSON, err := vmcompute.HcsGetProcessProperties(ctx, process.handle) |
|
| 193 |
+ propertiesJSON, resultJSON, err = vmcompute.HcsGetProcessProperties(ctx, process.handle) |
|
| 194 | 194 |
events := processHcsResult(ctx, resultJSON) |
| 195 | 195 |
if err != nil {
|
| 196 |
- err = makeProcessError(process, operation, err, events) |
|
| 196 |
+ err = makeProcessError(process, operation, err, events) //nolint:ineffassign |
|
| 197 | 197 |
} else {
|
| 198 | 198 |
properties := &processStatus{}
|
| 199 | 199 |
err = json.Unmarshal([]byte(propertiesJSON), properties) |
| 200 | 200 |
if err != nil {
|
| 201 |
- err = makeProcessError(process, operation, err, nil) |
|
| 201 |
+ err = makeProcessError(process, operation, err, nil) //nolint:ineffassign |
|
| 202 | 202 |
} else {
|
| 203 | 203 |
if properties.LastWaitResult != 0 {
|
| 204 | 204 |
log.G(ctx).WithField("wait-result", properties.LastWaitResult).Warning("non-zero last wait result")
|
| ... | ... |
@@ -468,7 +466,7 @@ func (process *Process) unregisterCallback(ctx context.Context) error {
|
| 468 | 468 |
delete(callbackMap, callbackNumber) |
| 469 | 469 |
callbackMapLock.Unlock() |
| 470 | 470 |
|
| 471 |
- handle = 0 |
|
| 471 |
+ handle = 0 //nolint:ineffassign |
|
| 472 | 472 |
|
| 473 | 473 |
return nil |
| 474 | 474 |
} |
| ... | ... |
@@ -73,8 +73,8 @@ func CreateComputeSystem(ctx context.Context, id string, hcsDocumentInterface in |
| 73 | 73 |
if err = computeSystem.registerCallback(ctx); err != nil {
|
| 74 | 74 |
// Terminate the compute system if it still exists. We're okay to |
| 75 | 75 |
// ignore a failure here. |
| 76 |
- computeSystem.Terminate(ctx) |
|
| 77 |
- return nil, makeSystemError(computeSystem, operation, "", err, nil) |
|
| 76 |
+ _ = computeSystem.Terminate(ctx) |
|
| 77 |
+ return nil, makeSystemError(computeSystem, operation, err, nil) |
|
| 78 | 78 |
} |
| 79 | 79 |
} |
| 80 | 80 |
|
| ... | ... |
@@ -83,9 +83,9 @@ func CreateComputeSystem(ctx context.Context, id string, hcsDocumentInterface in |
| 83 | 83 |
if err == ErrTimeout {
|
| 84 | 84 |
// Terminate the compute system if it still exists. We're okay to |
| 85 | 85 |
// ignore a failure here. |
| 86 |
- computeSystem.Terminate(ctx) |
|
| 86 |
+ _ = computeSystem.Terminate(ctx) |
|
| 87 | 87 |
} |
| 88 |
- return nil, makeSystemError(computeSystem, operation, hcsDocument, err, events) |
|
| 88 |
+ return nil, makeSystemError(computeSystem, operation, err, events) |
|
| 89 | 89 |
} |
| 90 | 90 |
go computeSystem.waitBackground() |
| 91 | 91 |
if err = computeSystem.getCachedProperties(ctx); err != nil {
|
| ... | ... |
@@ -102,7 +102,7 @@ func OpenComputeSystem(ctx context.Context, id string) (*System, error) {
|
| 102 | 102 |
handle, resultJSON, err := vmcompute.HcsOpenComputeSystem(ctx, id) |
| 103 | 103 |
events := processHcsResult(ctx, resultJSON) |
| 104 | 104 |
if err != nil {
|
| 105 |
- return nil, makeSystemError(computeSystem, operation, "", err, events) |
|
| 105 |
+ return nil, makeSystemError(computeSystem, operation, err, events) |
|
| 106 | 106 |
} |
| 107 | 107 |
computeSystem.handle = handle |
| 108 | 108 |
defer func() {
|
| ... | ... |
@@ -111,7 +111,7 @@ func OpenComputeSystem(ctx context.Context, id string) (*System, error) {
|
| 111 | 111 |
} |
| 112 | 112 |
}() |
| 113 | 113 |
if err = computeSystem.registerCallback(ctx); err != nil {
|
| 114 |
- return nil, makeSystemError(computeSystem, operation, "", err, nil) |
|
| 114 |
+ return nil, makeSystemError(computeSystem, operation, err, nil) |
|
| 115 | 115 |
} |
| 116 | 116 |
go computeSystem.waitBackground() |
| 117 | 117 |
if err = computeSystem.getCachedProperties(ctx); err != nil {
|
| ... | ... |
@@ -187,13 +187,13 @@ func (computeSystem *System) Start(ctx context.Context) (err error) {
|
| 187 | 187 |
defer computeSystem.handleLock.RUnlock() |
| 188 | 188 |
|
| 189 | 189 |
if computeSystem.handle == 0 {
|
| 190 |
- return makeSystemError(computeSystem, operation, "", ErrAlreadyClosed, nil) |
|
| 190 |
+ return makeSystemError(computeSystem, operation, ErrAlreadyClosed, nil) |
|
| 191 | 191 |
} |
| 192 | 192 |
|
| 193 | 193 |
resultJSON, err := vmcompute.HcsStartComputeSystem(ctx, computeSystem.handle, "") |
| 194 | 194 |
events, err := processAsyncHcsResult(ctx, err, resultJSON, computeSystem.callbackNumber, hcsNotificationSystemStartCompleted, &timeout.SystemStart) |
| 195 | 195 |
if err != nil {
|
| 196 |
- return makeSystemError(computeSystem, operation, "", err, events) |
|
| 196 |
+ return makeSystemError(computeSystem, operation, err, events) |
|
| 197 | 197 |
} |
| 198 | 198 |
|
| 199 | 199 |
return nil |
| ... | ... |
@@ -220,7 +220,7 @@ func (computeSystem *System) Shutdown(ctx context.Context) error {
|
| 220 | 220 |
switch err {
|
| 221 | 221 |
case nil, ErrVmcomputeAlreadyStopped, ErrComputeSystemDoesNotExist, ErrVmcomputeOperationPending: |
| 222 | 222 |
default: |
| 223 |
- return makeSystemError(computeSystem, operation, "", err, events) |
|
| 223 |
+ return makeSystemError(computeSystem, operation, err, events) |
|
| 224 | 224 |
} |
| 225 | 225 |
return nil |
| 226 | 226 |
} |
| ... | ... |
@@ -241,7 +241,7 @@ func (computeSystem *System) Terminate(ctx context.Context) error {
|
| 241 | 241 |
switch err {
|
| 242 | 242 |
case nil, ErrVmcomputeAlreadyStopped, ErrComputeSystemDoesNotExist, ErrVmcomputeOperationPending: |
| 243 | 243 |
default: |
| 244 |
- return makeSystemError(computeSystem, operation, "", err, events) |
|
| 244 |
+ return makeSystemError(computeSystem, operation, err, events) |
|
| 245 | 245 |
} |
| 246 | 246 |
return nil |
| 247 | 247 |
} |
| ... | ... |
@@ -263,10 +263,10 @@ func (computeSystem *System) waitBackground() {
|
| 263 | 263 |
log.G(ctx).Debug("system exited")
|
| 264 | 264 |
case ErrVmcomputeUnexpectedExit: |
| 265 | 265 |
log.G(ctx).Debug("unexpected system exit")
|
| 266 |
- computeSystem.exitError = makeSystemError(computeSystem, operation, "", err, nil) |
|
| 266 |
+ computeSystem.exitError = makeSystemError(computeSystem, operation, err, nil) |
|
| 267 | 267 |
err = nil |
| 268 | 268 |
default: |
| 269 |
- err = makeSystemError(computeSystem, operation, "", err, nil) |
|
| 269 |
+ err = makeSystemError(computeSystem, operation, err, nil) |
|
| 270 | 270 |
} |
| 271 | 271 |
computeSystem.closedWaitOnce.Do(func() {
|
| 272 | 272 |
computeSystem.waitError = err |
| ... | ... |
@@ -304,13 +304,13 @@ func (computeSystem *System) Properties(ctx context.Context, types ...schema1.Pr |
| 304 | 304 |
|
| 305 | 305 |
queryBytes, err := json.Marshal(schema1.PropertyQuery{PropertyTypes: types})
|
| 306 | 306 |
if err != nil {
|
| 307 |
- return nil, makeSystemError(computeSystem, operation, "", err, nil) |
|
| 307 |
+ return nil, makeSystemError(computeSystem, operation, err, nil) |
|
| 308 | 308 |
} |
| 309 | 309 |
|
| 310 | 310 |
propertiesJSON, resultJSON, err := vmcompute.HcsGetComputeSystemProperties(ctx, computeSystem.handle, string(queryBytes)) |
| 311 | 311 |
events := processHcsResult(ctx, resultJSON) |
| 312 | 312 |
if err != nil {
|
| 313 |
- return nil, makeSystemError(computeSystem, operation, "", err, events) |
|
| 313 |
+ return nil, makeSystemError(computeSystem, operation, err, events) |
|
| 314 | 314 |
} |
| 315 | 315 |
|
| 316 | 316 |
if propertiesJSON == "" {
|
| ... | ... |
@@ -318,7 +318,7 @@ func (computeSystem *System) Properties(ctx context.Context, types ...schema1.Pr |
| 318 | 318 |
} |
| 319 | 319 |
properties := &schema1.ContainerProperties{}
|
| 320 | 320 |
if err := json.Unmarshal([]byte(propertiesJSON), properties); err != nil {
|
| 321 |
- return nil, makeSystemError(computeSystem, operation, "", err, nil) |
|
| 321 |
+ return nil, makeSystemError(computeSystem, operation, err, nil) |
|
| 322 | 322 |
} |
| 323 | 323 |
|
| 324 | 324 |
return properties, nil |
| ... | ... |
@@ -333,13 +333,13 @@ func (computeSystem *System) PropertiesV2(ctx context.Context, types ...hcsschem |
| 333 | 333 |
|
| 334 | 334 |
queryBytes, err := json.Marshal(hcsschema.PropertyQuery{PropertyTypes: types})
|
| 335 | 335 |
if err != nil {
|
| 336 |
- return nil, makeSystemError(computeSystem, operation, "", err, nil) |
|
| 336 |
+ return nil, makeSystemError(computeSystem, operation, err, nil) |
|
| 337 | 337 |
} |
| 338 | 338 |
|
| 339 | 339 |
propertiesJSON, resultJSON, err := vmcompute.HcsGetComputeSystemProperties(ctx, computeSystem.handle, string(queryBytes)) |
| 340 | 340 |
events := processHcsResult(ctx, resultJSON) |
| 341 | 341 |
if err != nil {
|
| 342 |
- return nil, makeSystemError(computeSystem, operation, "", err, events) |
|
| 342 |
+ return nil, makeSystemError(computeSystem, operation, err, events) |
|
| 343 | 343 |
} |
| 344 | 344 |
|
| 345 | 345 |
if propertiesJSON == "" {
|
| ... | ... |
@@ -347,7 +347,7 @@ func (computeSystem *System) PropertiesV2(ctx context.Context, types ...hcsschem |
| 347 | 347 |
} |
| 348 | 348 |
properties := &hcsschema.Properties{}
|
| 349 | 349 |
if err := json.Unmarshal([]byte(propertiesJSON), properties); err != nil {
|
| 350 |
- return nil, makeSystemError(computeSystem, operation, "", err, nil) |
|
| 350 |
+ return nil, makeSystemError(computeSystem, operation, err, nil) |
|
| 351 | 351 |
} |
| 352 | 352 |
|
| 353 | 353 |
return properties, nil |
| ... | ... |
@@ -368,13 +368,13 @@ func (computeSystem *System) Pause(ctx context.Context) (err error) {
|
| 368 | 368 |
defer computeSystem.handleLock.RUnlock() |
| 369 | 369 |
|
| 370 | 370 |
if computeSystem.handle == 0 {
|
| 371 |
- return makeSystemError(computeSystem, operation, "", ErrAlreadyClosed, nil) |
|
| 371 |
+ return makeSystemError(computeSystem, operation, ErrAlreadyClosed, nil) |
|
| 372 | 372 |
} |
| 373 | 373 |
|
| 374 | 374 |
resultJSON, err := vmcompute.HcsPauseComputeSystem(ctx, computeSystem.handle, "") |
| 375 | 375 |
events, err := processAsyncHcsResult(ctx, err, resultJSON, computeSystem.callbackNumber, hcsNotificationSystemPauseCompleted, &timeout.SystemPause) |
| 376 | 376 |
if err != nil {
|
| 377 |
- return makeSystemError(computeSystem, operation, "", err, events) |
|
| 377 |
+ return makeSystemError(computeSystem, operation, err, events) |
|
| 378 | 378 |
} |
| 379 | 379 |
|
| 380 | 380 |
return nil |
| ... | ... |
@@ -395,13 +395,45 @@ func (computeSystem *System) Resume(ctx context.Context) (err error) {
|
| 395 | 395 |
defer computeSystem.handleLock.RUnlock() |
| 396 | 396 |
|
| 397 | 397 |
if computeSystem.handle == 0 {
|
| 398 |
- return makeSystemError(computeSystem, operation, "", ErrAlreadyClosed, nil) |
|
| 398 |
+ return makeSystemError(computeSystem, operation, ErrAlreadyClosed, nil) |
|
| 399 | 399 |
} |
| 400 | 400 |
|
| 401 | 401 |
resultJSON, err := vmcompute.HcsResumeComputeSystem(ctx, computeSystem.handle, "") |
| 402 | 402 |
events, err := processAsyncHcsResult(ctx, err, resultJSON, computeSystem.callbackNumber, hcsNotificationSystemResumeCompleted, &timeout.SystemResume) |
| 403 | 403 |
if err != nil {
|
| 404 |
- return makeSystemError(computeSystem, operation, "", err, events) |
|
| 404 |
+ return makeSystemError(computeSystem, operation, err, events) |
|
| 405 |
+ } |
|
| 406 |
+ |
|
| 407 |
+ return nil |
|
| 408 |
+} |
|
| 409 |
+ |
|
| 410 |
+// Save the compute system |
|
| 411 |
+func (computeSystem *System) Save(ctx context.Context, options interface{}) (err error) {
|
|
| 412 |
+ operation := "hcsshim::System::Save" |
|
| 413 |
+ |
|
| 414 |
+ // hcsSaveComputeSystemContext is an async peration. Start the outer span |
|
| 415 |
+ // here to measure the full save time. |
|
| 416 |
+ ctx, span := trace.StartSpan(ctx, operation) |
|
| 417 |
+ defer span.End() |
|
| 418 |
+ defer func() { oc.SetSpanStatus(span, err) }()
|
|
| 419 |
+ span.AddAttributes(trace.StringAttribute("cid", computeSystem.id))
|
|
| 420 |
+ |
|
| 421 |
+ saveOptions, err := json.Marshal(options) |
|
| 422 |
+ if err != nil {
|
|
| 423 |
+ return err |
|
| 424 |
+ } |
|
| 425 |
+ |
|
| 426 |
+ computeSystem.handleLock.RLock() |
|
| 427 |
+ defer computeSystem.handleLock.RUnlock() |
|
| 428 |
+ |
|
| 429 |
+ if computeSystem.handle == 0 {
|
|
| 430 |
+ return makeSystemError(computeSystem, operation, ErrAlreadyClosed, nil) |
|
| 431 |
+ } |
|
| 432 |
+ |
|
| 433 |
+ result, err := vmcompute.HcsSaveComputeSystem(ctx, computeSystem.handle, string(saveOptions)) |
|
| 434 |
+ events, err := processAsyncHcsResult(ctx, err, result, computeSystem.callbackNumber, hcsNotificationSystemSaveCompleted, &timeout.SystemSave) |
|
| 435 |
+ if err != nil {
|
|
| 436 |
+ return makeSystemError(computeSystem, operation, err, events) |
|
| 405 | 437 |
} |
| 406 | 438 |
|
| 407 | 439 |
return nil |
| ... | ... |
@@ -412,19 +444,19 @@ func (computeSystem *System) createProcess(ctx context.Context, operation string |
| 412 | 412 |
defer computeSystem.handleLock.RUnlock() |
| 413 | 413 |
|
| 414 | 414 |
if computeSystem.handle == 0 {
|
| 415 |
- return nil, nil, makeSystemError(computeSystem, operation, "", ErrAlreadyClosed, nil) |
|
| 415 |
+ return nil, nil, makeSystemError(computeSystem, operation, ErrAlreadyClosed, nil) |
|
| 416 | 416 |
} |
| 417 | 417 |
|
| 418 | 418 |
configurationb, err := json.Marshal(c) |
| 419 | 419 |
if err != nil {
|
| 420 |
- return nil, nil, makeSystemError(computeSystem, operation, "", err, nil) |
|
| 420 |
+ return nil, nil, makeSystemError(computeSystem, operation, err, nil) |
|
| 421 | 421 |
} |
| 422 | 422 |
|
| 423 | 423 |
configuration := string(configurationb) |
| 424 | 424 |
processInfo, processHandle, resultJSON, err := vmcompute.HcsCreateProcess(ctx, computeSystem.handle, configuration) |
| 425 | 425 |
events := processHcsResult(ctx, resultJSON) |
| 426 | 426 |
if err != nil {
|
| 427 |
- return nil, nil, makeSystemError(computeSystem, operation, configuration, err, events) |
|
| 427 |
+ return nil, nil, makeSystemError(computeSystem, operation, err, events) |
|
| 428 | 428 |
} |
| 429 | 429 |
|
| 430 | 430 |
log.G(ctx).WithField("pid", processInfo.ProcessId).Debug("created process pid")
|
| ... | ... |
@@ -446,7 +478,7 @@ func (computeSystem *System) CreateProcess(ctx context.Context, c interface{}) (
|
| 446 | 446 |
|
| 447 | 447 |
pipes, err := makeOpenFiles([]syscall.Handle{processInfo.StdInput, processInfo.StdOutput, processInfo.StdError})
|
| 448 | 448 |
if err != nil {
|
| 449 |
- return nil, makeSystemError(computeSystem, operation, "", err, nil) |
|
| 449 |
+ return nil, makeSystemError(computeSystem, operation, err, nil) |
|
| 450 | 450 |
} |
| 451 | 451 |
process.stdin = pipes[0] |
| 452 | 452 |
process.stdout = pipes[1] |
| ... | ... |
@@ -454,7 +486,7 @@ func (computeSystem *System) CreateProcess(ctx context.Context, c interface{}) (
|
| 454 | 454 |
process.hasCachedStdio = true |
| 455 | 455 |
|
| 456 | 456 |
if err = process.registerCallback(ctx); err != nil {
|
| 457 |
- return nil, makeSystemError(computeSystem, operation, "", err, nil) |
|
| 457 |
+ return nil, makeSystemError(computeSystem, operation, err, nil) |
|
| 458 | 458 |
} |
| 459 | 459 |
go process.waitBackground() |
| 460 | 460 |
|
| ... | ... |
@@ -469,18 +501,18 @@ func (computeSystem *System) OpenProcess(ctx context.Context, pid int) (*Process |
| 469 | 469 |
operation := "hcsshim::System::OpenProcess" |
| 470 | 470 |
|
| 471 | 471 |
if computeSystem.handle == 0 {
|
| 472 |
- return nil, makeSystemError(computeSystem, operation, "", ErrAlreadyClosed, nil) |
|
| 472 |
+ return nil, makeSystemError(computeSystem, operation, ErrAlreadyClosed, nil) |
|
| 473 | 473 |
} |
| 474 | 474 |
|
| 475 | 475 |
processHandle, resultJSON, err := vmcompute.HcsOpenProcess(ctx, computeSystem.handle, uint32(pid)) |
| 476 | 476 |
events := processHcsResult(ctx, resultJSON) |
| 477 | 477 |
if err != nil {
|
| 478 |
- return nil, makeSystemError(computeSystem, operation, "", err, events) |
|
| 478 |
+ return nil, makeSystemError(computeSystem, operation, err, events) |
|
| 479 | 479 |
} |
| 480 | 480 |
|
| 481 | 481 |
process := newProcess(processHandle, pid, computeSystem) |
| 482 | 482 |
if err = process.registerCallback(ctx); err != nil {
|
| 483 |
- return nil, makeSystemError(computeSystem, operation, "", err, nil) |
|
| 483 |
+ return nil, makeSystemError(computeSystem, operation, err, nil) |
|
| 484 | 484 |
} |
| 485 | 485 |
go process.waitBackground() |
| 486 | 486 |
|
| ... | ... |
@@ -504,12 +536,12 @@ func (computeSystem *System) Close() (err error) {
|
| 504 | 504 |
} |
| 505 | 505 |
|
| 506 | 506 |
if err = computeSystem.unregisterCallback(ctx); err != nil {
|
| 507 |
- return makeSystemError(computeSystem, operation, "", err, nil) |
|
| 507 |
+ return makeSystemError(computeSystem, operation, err, nil) |
|
| 508 | 508 |
} |
| 509 | 509 |
|
| 510 | 510 |
err = vmcompute.HcsCloseComputeSystem(ctx, computeSystem.handle) |
| 511 | 511 |
if err != nil {
|
| 512 |
- return makeSystemError(computeSystem, operation, "", err, nil) |
|
| 512 |
+ return makeSystemError(computeSystem, operation, err, nil) |
|
| 513 | 513 |
} |
| 514 | 514 |
|
| 515 | 515 |
computeSystem.handle = 0 |
| ... | ... |
@@ -573,7 +605,7 @@ func (computeSystem *System) unregisterCallback(ctx context.Context) error {
|
| 573 | 573 |
delete(callbackMap, callbackNumber) |
| 574 | 574 |
callbackMapLock.Unlock() |
| 575 | 575 |
|
| 576 |
- handle = 0 |
|
| 576 |
+ handle = 0 //nolint:ineffassign |
|
| 577 | 577 |
|
| 578 | 578 |
return nil |
| 579 | 579 |
} |
| ... | ... |
@@ -586,7 +618,7 @@ func (computeSystem *System) Modify(ctx context.Context, config interface{}) err
|
| 586 | 586 |
operation := "hcsshim::System::Modify" |
| 587 | 587 |
|
| 588 | 588 |
if computeSystem.handle == 0 {
|
| 589 |
- return makeSystemError(computeSystem, operation, "", ErrAlreadyClosed, nil) |
|
| 589 |
+ return makeSystemError(computeSystem, operation, ErrAlreadyClosed, nil) |
|
| 590 | 590 |
} |
| 591 | 591 |
|
| 592 | 592 |
requestBytes, err := json.Marshal(config) |
| ... | ... |
@@ -598,7 +630,7 @@ func (computeSystem *System) Modify(ctx context.Context, config interface{}) err
|
| 598 | 598 |
resultJSON, err := vmcompute.HcsModifyComputeSystem(ctx, computeSystem.handle, requestJSON) |
| 599 | 599 |
events := processHcsResult(ctx, resultJSON) |
| 600 | 600 |
if err != nil {
|
| 601 |
- return makeSystemError(computeSystem, operation, requestJSON, err, events) |
|
| 601 |
+ return makeSystemError(computeSystem, operation, err, events) |
|
| 602 | 602 |
} |
| 603 | 603 |
|
| 604 | 604 |
return nil |
| ... | ... |
@@ -7,6 +7,7 @@ import ( |
| 7 | 7 |
|
| 8 | 8 |
"github.com/Microsoft/go-winio" |
| 9 | 9 |
diskutil "github.com/Microsoft/go-winio/vhd" |
| 10 |
+ "github.com/Microsoft/hcsshim/computestorage" |
|
| 10 | 11 |
"github.com/pkg/errors" |
| 11 | 12 |
"golang.org/x/sys/windows" |
| 12 | 13 |
) |
| ... | ... |
@@ -36,7 +37,7 @@ func makeOpenFiles(hs []syscall.Handle) (_ []io.ReadWriteCloser, err error) {
|
| 36 | 36 |
return fs, nil |
| 37 | 37 |
} |
| 38 | 38 |
|
| 39 |
-// creates a VHD formatted with NTFS of size `sizeGB` at the given `vhdPath`. |
|
| 39 |
+// CreateNTFSVHD creates a VHD formatted with NTFS of size `sizeGB` at the given `vhdPath`. |
|
| 40 | 40 |
func CreateNTFSVHD(ctx context.Context, vhdPath string, sizeGB uint32) (err error) {
|
| 41 | 41 |
if err := diskutil.CreateVhdx(vhdPath, sizeGB, 1); err != nil {
|
| 42 | 42 |
return errors.Wrap(err, "failed to create VHD") |
| ... | ... |
@@ -53,7 +54,7 @@ func CreateNTFSVHD(ctx context.Context, vhdPath string, sizeGB uint32) (err erro |
| 53 | 53 |
} |
| 54 | 54 |
}() |
| 55 | 55 |
|
| 56 |
- if err := hcsFormatWritableLayerVhd(uintptr(vhd)); err != nil {
|
|
| 56 |
+ if err := computestorage.FormatWritableLayerVhd(ctx, windows.Handle(vhd)); err != nil {
|
|
| 57 | 57 |
return errors.Wrap(err, "failed to format VHD") |
| 58 | 58 |
} |
| 59 | 59 |
|
| 70 | 69 |
deleted file mode 100644 |
| ... | ... |
@@ -1,54 +0,0 @@ |
| 1 |
-// Code generated mksyscall_windows.exe DO NOT EDIT |
|
| 2 |
- |
|
| 3 |
-package hcs |
|
| 4 |
- |
|
| 5 |
-import ( |
|
| 6 |
- "syscall" |
|
| 7 |
- "unsafe" |
|
| 8 |
- |
|
| 9 |
- "golang.org/x/sys/windows" |
|
| 10 |
-) |
|
| 11 |
- |
|
| 12 |
-var _ unsafe.Pointer |
|
| 13 |
- |
|
| 14 |
-// Do the interface allocations only once for common |
|
| 15 |
-// Errno values. |
|
| 16 |
-const ( |
|
| 17 |
- errnoERROR_IO_PENDING = 997 |
|
| 18 |
-) |
|
| 19 |
- |
|
| 20 |
-var ( |
|
| 21 |
- errERROR_IO_PENDING error = syscall.Errno(errnoERROR_IO_PENDING) |
|
| 22 |
-) |
|
| 23 |
- |
|
| 24 |
-// errnoErr returns common boxed Errno values, to prevent |
|
| 25 |
-// allocations at runtime. |
|
| 26 |
-func errnoErr(e syscall.Errno) error {
|
|
| 27 |
- switch e {
|
|
| 28 |
- case 0: |
|
| 29 |
- return nil |
|
| 30 |
- case errnoERROR_IO_PENDING: |
|
| 31 |
- return errERROR_IO_PENDING |
|
| 32 |
- } |
|
| 33 |
- // TODO: add more here, after collecting data on the common |
|
| 34 |
- // error values see on Windows. (perhaps when running |
|
| 35 |
- // all.bat?) |
|
| 36 |
- return e |
|
| 37 |
-} |
|
| 38 |
- |
|
| 39 |
-var ( |
|
| 40 |
- modcomputestorage = windows.NewLazySystemDLL("computestorage.dll")
|
|
| 41 |
- |
|
| 42 |
- procHcsFormatWritableLayerVhd = modcomputestorage.NewProc("HcsFormatWritableLayerVhd")
|
|
| 43 |
-) |
|
| 44 |
- |
|
| 45 |
-func hcsFormatWritableLayerVhd(handle uintptr) (hr error) {
|
|
| 46 |
- r0, _, _ := syscall.Syscall(procHcsFormatWritableLayerVhd.Addr(), 1, uintptr(handle), 0, 0) |
|
| 47 |
- if int32(r0) < 0 {
|
|
| 48 |
- if r0&0x1fff0000 == 0x00070000 {
|
|
| 49 |
- r0 &= 0xffff |
|
| 50 |
- } |
|
| 51 |
- hr = syscall.Errno(r0) |
|
| 52 |
- } |
|
| 53 |
- return |
|
| 54 |
-} |
| ... | ... |
@@ -27,9 +27,10 @@ type namespaceResourceRequest struct {
|
| 27 | 27 |
} |
| 28 | 28 |
|
| 29 | 29 |
type Namespace struct {
|
| 30 |
- ID string |
|
| 31 |
- IsDefault bool `json:",omitempty"` |
|
| 32 |
- ResourceList []NamespaceResource `json:",omitempty"` |
|
| 30 |
+ ID string |
|
| 31 |
+ IsDefault bool `json:",omitempty"` |
|
| 32 |
+ ResourceList []NamespaceResource `json:",omitempty"` |
|
| 33 |
+ CompartmentId uint32 `json:",omitempty"` |
|
| 33 | 34 |
} |
| 34 | 35 |
|
| 35 | 36 |
func issueNamespaceRequest(id *string, method, subpath string, request interface{}) (*Namespace, error) {
|
| ... | ... |
@@ -76,7 +76,7 @@ func openRelativeInternal(path string, root *os.File, accessMask uint32, shareFl |
| 76 | 76 |
} |
| 77 | 77 |
|
| 78 | 78 |
oa.Length = unsafe.Sizeof(oa) |
| 79 |
- oa.ObjectName = uintptr(unsafe.Pointer(pathUnicode)) |
|
| 79 |
+ oa.ObjectName = pathUnicode |
|
| 80 | 80 |
oa.RootDirectory = uintptr(root.Fd()) |
| 81 | 81 |
oa.Attributes = winapi.OBJ_DONT_REPARSE |
| 82 | 82 |
status := winapi.NtCreateFile( |
| ... | ... |
@@ -177,7 +177,7 @@ func LinkRelative(oldname string, oldroot *os.File, newname string, newroot *os. |
| 177 | 177 |
linkinfo := (*winapi.FileLinkInformation)(unsafe.Pointer(linkinfoBuffer)) |
| 178 | 178 |
linkinfo.RootDirectory = parent.Fd() |
| 179 | 179 |
linkinfo.FileNameLength = uint32(len(newbase16) * 2) |
| 180 |
- copy((*[32768]uint16)(unsafe.Pointer(&linkinfo.FileName[0]))[:], newbase16) |
|
| 180 |
+ copy(winapi.Uint16BufferToSlice(&linkinfo.FileName[0], len(newbase16)), newbase16) |
|
| 181 | 181 |
|
| 182 | 182 |
var iosb winapi.IOStatusBlock |
| 183 | 183 |
status := winapi.NtSetInformationFile( |
| ... | ... |
@@ -244,7 +244,7 @@ func RemoveRelative(path string, root *os.File) error {
|
| 244 | 244 |
err = deleteOnClose(f) |
| 245 | 245 |
if err == syscall.ERROR_ACCESS_DENIED {
|
| 246 | 246 |
// Maybe the file is marked readonly. Clear the bit and retry. |
| 247 |
- clearReadOnly(f) |
|
| 247 |
+ _ = clearReadOnly(f) |
|
| 248 | 248 |
err = deleteOnClose(f) |
| 249 | 249 |
} |
| 250 | 250 |
} |
| ... | ... |
@@ -119,9 +119,9 @@ type PropertyType string |
| 119 | 119 |
|
| 120 | 120 |
const ( |
| 121 | 121 |
PropertyTypeStatistics PropertyType = "Statistics" // V1 and V2 |
| 122 |
- PropertyTypeProcessList = "ProcessList" // V1 and V2 |
|
| 123 |
- PropertyTypeMappedVirtualDisk = "MappedVirtualDisk" // Not supported in V2 schema call |
|
| 124 |
- PropertyTypeGuestConnection = "GuestConnection" // V1 and V2. Nil return from HCS before RS5 |
|
| 122 |
+ PropertyTypeProcessList PropertyType = "ProcessList" // V1 and V2 |
|
| 123 |
+ PropertyTypeMappedVirtualDisk PropertyType = "MappedVirtualDisk" // Not supported in V2 schema call |
|
| 124 |
+ PropertyTypeGuestConnection PropertyType = "GuestConnection" // V1 and V2. Nil return from HCS before RS5 |
|
| 125 | 125 |
) |
| 126 | 126 |
|
| 127 | 127 |
type PropertyQuery struct {
|
| ... | ... |
@@ -218,6 +218,7 @@ type GuestDefinedCapabilities struct {
|
| 218 | 218 |
SignalProcessSupported bool `json:",omitempty"` |
| 219 | 219 |
DumpStacksSupported bool `json:",omitempty"` |
| 220 | 220 |
DeleteContainerStateSupported bool `json:",omitempty"` |
| 221 |
+ UpdateContainerSupported bool `json:",omitempty"` |
|
| 221 | 222 |
} |
| 222 | 223 |
|
| 223 | 224 |
// GuestConnectionInfo is the structure of an iterm return by a GuestConnection call on a utility VM |
| 224 | 225 |
new file mode 100644 |
| ... | ... |
@@ -0,0 +1,15 @@ |
| 0 |
+/* |
|
| 1 |
+ * HCS API |
|
| 2 |
+ * |
|
| 3 |
+ * No description provided (generated by Swagger Codegen https://github.com/swagger-api/swagger-codegen) |
|
| 4 |
+ * |
|
| 5 |
+ * API version: 2.4 |
|
| 6 |
+ * Generated by: Swagger Codegen (https://github.com/swagger-api/swagger-codegen.git) |
|
| 7 |
+ */ |
|
| 8 |
+ |
|
| 9 |
+package hcsschema |
|
| 10 |
+ |
|
| 11 |
+// CPU groups allow Hyper-V administrators to better manage and allocate the host's CPU resources across guest virtual machines |
|
| 12 |
+type CpuGroup struct {
|
|
| 13 |
+ Id string `json:"Id,omitempty"` |
|
| 14 |
+} |
| 0 | 15 |
new file mode 100644 |
| ... | ... |
@@ -0,0 +1,15 @@ |
| 0 |
+/* |
|
| 1 |
+ * HCS API |
|
| 2 |
+ * |
|
| 3 |
+ * No description provided (generated by Swagger Codegen https://github.com/swagger-api/swagger-codegen) |
|
| 4 |
+ * |
|
| 5 |
+ * API version: 2.4 |
|
| 6 |
+ * Generated by: Swagger Codegen (https://github.com/swagger-api/swagger-codegen.git) |
|
| 7 |
+ */ |
|
| 8 |
+ |
|
| 9 |
+package hcsschema |
|
| 10 |
+ |
|
| 11 |
+type CpuGroupAffinity struct {
|
|
| 12 |
+ LogicalProcessorCount int32 `json:"LogicalProcessorCount,omitempty"` |
|
| 13 |
+ LogicalProcessors []int32 `json:"LogicalProcessors,omitempty"` |
|
| 14 |
+} |
| 0 | 15 |
new file mode 100644 |
| ... | ... |
@@ -0,0 +1,18 @@ |
| 0 |
+/* |
|
| 1 |
+ * HCS API |
|
| 2 |
+ * |
|
| 3 |
+ * No description provided (generated by Swagger Codegen https://github.com/swagger-api/swagger-codegen) |
|
| 4 |
+ * |
|
| 5 |
+ * API version: 2.4 |
|
| 6 |
+ * Generated by: Swagger Codegen (https://github.com/swagger-api/swagger-codegen.git) |
|
| 7 |
+ */ |
|
| 8 |
+ |
|
| 9 |
+package hcsschema |
|
| 10 |
+ |
|
| 11 |
+type CpuGroupConfig struct {
|
|
| 12 |
+ GroupId string `json:"GroupId,omitempty"` |
|
| 13 |
+ Affinity *CpuGroupAffinity `json:"Affinity,omitempty"` |
|
| 14 |
+ GroupProperties []CpuGroupProperty `json:"GroupProperties,omitempty"` |
|
| 15 |
+ // Hypervisor CPU group IDs exposed to clients |
|
| 16 |
+ HypervisorGroupId int32 `json:"HypervisorGroupId,omitempty"` |
|
| 17 |
+} |
| 0 | 18 |
new file mode 100644 |
| ... | ... |
@@ -0,0 +1,15 @@ |
| 0 |
+/* |
|
| 1 |
+ * HCS API |
|
| 2 |
+ * |
|
| 3 |
+ * No description provided (generated by Swagger Codegen https://github.com/swagger-api/swagger-codegen) |
|
| 4 |
+ * |
|
| 5 |
+ * API version: 2.4 |
|
| 6 |
+ * Generated by: Swagger Codegen (https://github.com/swagger-api/swagger-codegen.git) |
|
| 7 |
+ */ |
|
| 8 |
+ |
|
| 9 |
+package hcsschema |
|
| 10 |
+ |
|
| 11 |
+// Structure used to return cpu groups for a Service property query |
|
| 12 |
+type CpuGroupConfigurations struct {
|
|
| 13 |
+ CpuGroups []CpuGroupConfig `json:"CpuGroups,omitempty"` |
|
| 14 |
+} |
| 0 | 15 |
new file mode 100644 |
| ... | ... |
@@ -0,0 +1,18 @@ |
| 0 |
+/* |
|
| 1 |
+ * HCS API |
|
| 2 |
+ * |
|
| 3 |
+ * No description provided (generated by Swagger Codegen https://github.com/swagger-api/swagger-codegen) |
|
| 4 |
+ * |
|
| 5 |
+ * API version: 2.4 |
|
| 6 |
+ * Generated by: Swagger Codegen (https://github.com/swagger-api/swagger-codegen.git) |
|
| 7 |
+ */ |
|
| 8 |
+ |
|
| 9 |
+package hcsschema |
|
| 10 |
+ |
|
| 11 |
+type CPUGroupOperation string |
|
| 12 |
+ |
|
| 13 |
+const ( |
|
| 14 |
+ CreateGroup CPUGroupOperation = "CreateGroup" |
|
| 15 |
+ DeleteGroup CPUGroupOperation = "DeleteGroup" |
|
| 16 |
+ SetProperty CPUGroupOperation = "SetProperty" |
|
| 17 |
+) |
| 0 | 18 |
new file mode 100644 |
| ... | ... |
@@ -0,0 +1,15 @@ |
| 0 |
+/* |
|
| 1 |
+ * HCS API |
|
| 2 |
+ * |
|
| 3 |
+ * No description provided (generated by Swagger Codegen https://github.com/swagger-api/swagger-codegen) |
|
| 4 |
+ * |
|
| 5 |
+ * API version: 2.4 |
|
| 6 |
+ * Generated by: Swagger Codegen (https://github.com/swagger-api/swagger-codegen.git) |
|
| 7 |
+ */ |
|
| 8 |
+ |
|
| 9 |
+package hcsschema |
|
| 10 |
+ |
|
| 11 |
+type CpuGroupProperty struct {
|
|
| 12 |
+ PropertyCode uint32 `json:"PropertyCode,omitempty"` |
|
| 13 |
+ PropertyValue uint32 `json:"PropertyValue,omitempty"` |
|
| 14 |
+} |
| 0 | 15 |
new file mode 100644 |
| ... | ... |
@@ -0,0 +1,17 @@ |
| 0 |
+/* |
|
| 1 |
+ * HCS API |
|
| 2 |
+ * |
|
| 3 |
+ * No description provided (generated by Swagger Codegen https://github.com/swagger-api/swagger-codegen) |
|
| 4 |
+ * |
|
| 5 |
+ * API version: 2.4 |
|
| 6 |
+ * Generated by: Swagger Codegen (https://github.com/swagger-api/swagger-codegen.git) |
|
| 7 |
+ */ |
|
| 8 |
+ |
|
| 9 |
+package hcsschema |
|
| 10 |
+ |
|
| 11 |
+// Create group operation settings |
|
| 12 |
+type CreateGroupOperation struct {
|
|
| 13 |
+ GroupId string `json:"GroupId,omitempty"` |
|
| 14 |
+ LogicalProcessorCount uint32 `json:"LogicalProcessorCount,omitempty"` |
|
| 15 |
+ LogicalProcessors []uint32 `json:"LogicalProcessors,omitempty"` |
|
| 16 |
+} |
| 0 | 17 |
new file mode 100644 |
| ... | ... |
@@ -0,0 +1,15 @@ |
| 0 |
+/* |
|
| 1 |
+ * HCS API |
|
| 2 |
+ * |
|
| 3 |
+ * No description provided (generated by Swagger Codegen https://github.com/swagger-api/swagger-codegen) |
|
| 4 |
+ * |
|
| 5 |
+ * API version: 2.4 |
|
| 6 |
+ * Generated by: Swagger Codegen (https://github.com/swagger-api/swagger-codegen.git) |
|
| 7 |
+ */ |
|
| 8 |
+ |
|
| 9 |
+package hcsschema |
|
| 10 |
+ |
|
| 11 |
+// Delete group operation settings |
|
| 12 |
+type DeleteGroupOperation struct {
|
|
| 13 |
+ GroupId string `json:"GroupId,omitempty"` |
|
| 14 |
+} |
| ... | ... |
@@ -13,8 +13,8 @@ type DeviceType string |
| 13 | 13 |
|
| 14 | 14 |
const ( |
| 15 | 15 |
ClassGUID DeviceType = "ClassGuid" |
| 16 |
- DeviceInstance = "DeviceInstance" |
|
| 17 |
- GPUMirror = "GpuMirror" |
|
| 16 |
+ DeviceInstance DeviceType = "DeviceInstance" |
|
| 17 |
+ GPUMirror DeviceType = "GpuMirror" |
|
| 18 | 18 |
) |
| 19 | 19 |
|
| 20 | 20 |
type Device struct {
|
| 21 | 21 |
new file mode 100644 |
| ... | ... |
@@ -0,0 +1,16 @@ |
| 0 |
+/* |
|
| 1 |
+ * HCS API |
|
| 2 |
+ * |
|
| 3 |
+ * No description provided (generated by Swagger Codegen https://github.com/swagger-api/swagger-codegen) |
|
| 4 |
+ * |
|
| 5 |
+ * API version: 2.4 |
|
| 6 |
+ * Generated by: Swagger Codegen (https://github.com/swagger-api/swagger-codegen.git) |
|
| 7 |
+ */ |
|
| 8 |
+ |
|
| 9 |
+package hcsschema |
|
| 10 |
+ |
|
| 11 |
+// Structure used to request a service processor modification |
|
| 12 |
+type HostProcessorModificationRequest struct {
|
|
| 13 |
+ Operation CPUGroupOperation `json:"Operation,omitempty"` |
|
| 14 |
+ OperationDetails interface{} `json:"OperationDetails,omitempty"`
|
|
| 15 |
+} |
| ... | ... |
@@ -19,4 +19,10 @@ type HvSocketServiceConfig struct {
|
| 19 | 19 |
|
| 20 | 20 |
// If true, HvSocket will process wildcard binds for this service/system combination. Wildcard binds are secured in the registry at SOFTWARE/Microsoft/Windows NT/CurrentVersion/Virtualization/HvSocket/WildcardDescriptors |
| 21 | 21 |
AllowWildcardBinds bool `json:"AllowWildcardBinds,omitempty"` |
| 22 |
+ |
|
| 23 |
+ // Disabled controls whether the HvSocket service is accepting connection requests. |
|
| 24 |
+ // This set to true will make the service refuse all incoming connections as well as cancel |
|
| 25 |
+ // any connections already established. The service itself will still be active however |
|
| 26 |
+ // and can be re-enabled at a future time. |
|
| 27 |
+ Disabled bool `json:"Disabled,omitempty"` |
|
| 22 | 28 |
} |
| 23 | 29 |
new file mode 100644 |
| ... | ... |
@@ -0,0 +1,42 @@ |
| 0 |
+/* |
|
| 1 |
+ * HCS API |
|
| 2 |
+ * |
|
| 3 |
+ * No description provided (generated by Swagger Codegen https://github.com/swagger-api/swagger-codegen) |
|
| 4 |
+ * |
|
| 5 |
+ * API version: 2.4 |
|
| 6 |
+ * Generated by: Swagger Codegen (https://github.com/swagger-api/swagger-codegen.git) |
|
| 7 |
+ */ |
|
| 8 |
+ |
|
| 9 |
+package hcsschema |
|
| 10 |
+ |
|
| 11 |
+type InterruptModerationName string |
|
| 12 |
+ |
|
| 13 |
+// The valid interrupt moderation modes for I/O virtualization (IOV) offloading. |
|
| 14 |
+const ( |
|
| 15 |
+ DefaultName InterruptModerationName = "Default" |
|
| 16 |
+ AdaptiveName InterruptModerationName = "Adaptive" |
|
| 17 |
+ OffName InterruptModerationName = "Off" |
|
| 18 |
+ LowName InterruptModerationName = "Low" |
|
| 19 |
+ MediumName InterruptModerationName = "Medium" |
|
| 20 |
+ HighName InterruptModerationName = "High" |
|
| 21 |
+) |
|
| 22 |
+ |
|
| 23 |
+type InterruptModerationValue uint32 |
|
| 24 |
+ |
|
| 25 |
+const ( |
|
| 26 |
+ DefaultValue InterruptModerationValue = iota |
|
| 27 |
+ AdaptiveValue |
|
| 28 |
+ OffValue |
|
| 29 |
+ LowValue InterruptModerationValue = 100 |
|
| 30 |
+ MediumValue InterruptModerationValue = 200 |
|
| 31 |
+ HighValue InterruptModerationValue = 300 |
|
| 32 |
+) |
|
| 33 |
+ |
|
| 34 |
+var InterruptModerationValueToName = map[InterruptModerationValue]InterruptModerationName{
|
|
| 35 |
+ DefaultValue: DefaultName, |
|
| 36 |
+ AdaptiveValue: AdaptiveName, |
|
| 37 |
+ OffValue: OffName, |
|
| 38 |
+ LowValue: LowName, |
|
| 39 |
+ MediumValue: MediumName, |
|
| 40 |
+ HighValue: HighName, |
|
| 41 |
+} |
| 0 | 42 |
new file mode 100644 |
| ... | ... |
@@ -0,0 +1,22 @@ |
| 0 |
+/* |
|
| 1 |
+ * HCS API |
|
| 2 |
+ * |
|
| 3 |
+ * No description provided (generated by Swagger Codegen https://github.com/swagger-api/swagger-codegen) |
|
| 4 |
+ * |
|
| 5 |
+ * API version: 2.4 |
|
| 6 |
+ * Generated by: Swagger Codegen (https://github.com/swagger-api/swagger-codegen.git) |
|
| 7 |
+ */ |
|
| 8 |
+ |
|
| 9 |
+package hcsschema |
|
| 10 |
+ |
|
| 11 |
+type IovSettings struct {
|
|
| 12 |
+ // The weight assigned to this port for I/O virtualization (IOV) offloading. |
|
| 13 |
+ // Setting this to 0 disables IOV offloading. |
|
| 14 |
+ OffloadWeight *uint32 `json:"OffloadWeight,omitempty"` |
|
| 15 |
+ |
|
| 16 |
+ // The number of queue pairs requested for this port for I/O virtualization (IOV) offloading. |
|
| 17 |
+ QueuePairsRequested *uint32 `json:"QueuePairsRequested,omitempty"` |
|
| 18 |
+ |
|
| 19 |
+ // The interrupt moderation mode for I/O virtualization (IOV) offloading. |
|
| 20 |
+ InterruptModeration *InterruptModerationName `json:"InterruptModeration,omitempty"` |
|
| 21 |
+} |
| ... | ... |
@@ -11,8 +11,8 @@ package hcsschema |
| 11 | 11 |
|
| 12 | 12 |
type LogicalProcessor struct {
|
| 13 | 13 |
LpIndex uint32 `json:"LpIndex,omitempty"` |
| 14 |
- NodeNumber uint8 `json:"NodeNumber, omitempty"` |
|
| 15 |
- PackageId uint32 `json:"PackageId, omitempty"` |
|
| 16 |
- CoreId uint32 `json:"CoreId, omitempty"` |
|
| 17 |
- RootVpIndex int32 `json:"RootVpIndex, omitempty"` |
|
| 14 |
+ NodeNumber uint8 `json:"NodeNumber,omitempty"` |
|
| 15 |
+ PackageId uint32 `json:"PackageId,omitempty"` |
|
| 16 |
+ CoreId uint32 `json:"CoreId,omitempty"` |
|
| 17 |
+ RootVpIndex int32 `json:"RootVpIndex,omitempty"` |
|
| 18 | 18 |
} |
| ... | ... |
@@ -11,6 +11,7 @@ package hcsschema |
| 11 | 11 |
|
| 12 | 12 |
type NetworkAdapter struct {
|
| 13 | 13 |
EndpointId string `json:"EndpointId,omitempty"` |
| 14 |
- |
|
| 15 | 14 |
MacAddress string `json:"MacAddress,omitempty"` |
| 15 |
+ // The I/O virtualization (IOV) offloading configuration. |
|
| 16 |
+ IovSettings *IovSettings `json:"IovSettings,omitempty"` |
|
| 16 | 17 |
} |
| 26 | 27 |
new file mode 100644 |
| ... | ... |
@@ -0,0 +1,22 @@ |
| 0 |
+/* |
|
| 1 |
+ * HCS API |
|
| 2 |
+ * |
|
| 3 |
+ * No description provided (generated by Swagger Codegen https://github.com/swagger-api/swagger-codegen) |
|
| 4 |
+ * |
|
| 5 |
+ * API version: 2.4 |
|
| 6 |
+ * Generated by: Swagger Codegen (https://github.com/swagger-api/swagger-codegen.git) |
|
| 7 |
+ */ |
|
| 8 |
+ |
|
| 9 |
+package hcsschema |
|
| 10 |
+ |
|
| 11 |
+// ProcessorLimits is used when modifying processor scheduling limits of a virtual machine. |
|
| 12 |
+type ProcessorLimits struct {
|
|
| 13 |
+ // Maximum amount of host CPU resources that the virtual machine can use. |
|
| 14 |
+ Limit uint64 `json:"Limit,omitempty"` |
|
| 15 |
+ // Value describing the relative priority of this virtual machine compared to other virtual machines. |
|
| 16 |
+ Weight uint64 `json:"Weight,omitempty"` |
|
| 17 |
+ // Minimum amount of host CPU resources that the virtual machine is guaranteed. |
|
| 18 |
+ Reservation uint64 `json:"Reservation,omitempty"` |
|
| 19 |
+ // Provides the target maximum CPU frequency, in MHz, for a virtual machine. |
|
| 20 |
+ MaximumFrequencyMHz uint32 `json:"MaximumFrequencyMHz,omitempty"` |
|
| 21 |
+} |
| ... | ... |
@@ -29,6 +29,9 @@ var ( |
| 29 | 29 |
// SystemResume is the timeout for resuming a compute system |
| 30 | 30 |
SystemResume time.Duration = defaultTimeout |
| 31 | 31 |
|
| 32 |
+ // SystemSave is the timeout for saving a compute system |
|
| 33 |
+ SystemSave time.Duration = defaultTimeout |
|
| 34 |
+ |
|
| 32 | 35 |
// SyscallWatcher is the timeout before warning of a potential stuck platform syscall. |
| 33 | 36 |
SyscallWatcher time.Duration = defaultTimeout |
| 34 | 37 |
|
| ... | ... |
@@ -51,6 +54,7 @@ func init() {
|
| 51 | 51 |
SystemStart = durationFromEnvironment("HCSSHIM_TIMEOUT_SYSTEMSTART", SystemStart)
|
| 52 | 52 |
SystemPause = durationFromEnvironment("HCSSHIM_TIMEOUT_SYSTEMPAUSE", SystemPause)
|
| 53 | 53 |
SystemResume = durationFromEnvironment("HCSSHIM_TIMEOUT_SYSTEMRESUME", SystemResume)
|
| 54 |
+ SystemSave = durationFromEnvironment("HCSSHIM_TIMEOUT_SYSTEMSAVE", SystemSave)
|
|
| 54 | 55 |
SyscallWatcher = durationFromEnvironment("HCSSHIM_TIMEOUT_SYSCALLWATCHER", SyscallWatcher)
|
| 55 | 56 |
Tar2VHD = durationFromEnvironment("HCSSHIM_TIMEOUT_TAR2VHD", Tar2VHD)
|
| 56 | 57 |
ExternalCommandToStart = durationFromEnvironment("HCSSHIM_TIMEOUT_EXTERNALCOMMANDSTART", ExternalCommandToStart)
|
| ... | ... |
@@ -29,6 +29,7 @@ import ( |
| 29 | 29 |
//sys hcsModifyServiceSettings(settings string, result **uint16) (hr error) = vmcompute.HcsModifyServiceSettings? |
| 30 | 30 |
//sys hcsRegisterComputeSystemCallback(computeSystem HcsSystem, callback uintptr, context uintptr, callbackHandle *HcsCallback) (hr error) = vmcompute.HcsRegisterComputeSystemCallback? |
| 31 | 31 |
//sys hcsUnregisterComputeSystemCallback(callbackHandle HcsCallback) (hr error) = vmcompute.HcsUnregisterComputeSystemCallback? |
| 32 |
+//sys hcsSaveComputeSystem(computeSystem HcsSystem, options string, result **uint16) (hr error) = vmcompute.HcsSaveComputeSystem? |
|
| 32 | 33 |
|
| 33 | 34 |
//sys hcsCreateProcess(computeSystem HcsSystem, processParameters string, processInformation *HcsProcessInformation, process *HcsProcess, result **uint16) (hr error) = vmcompute.HcsCreateProcess? |
| 34 | 35 |
//sys hcsOpenProcess(computeSystem HcsSystem, pid uint32, process *HcsProcess, result **uint16) (hr error) = vmcompute.HcsOpenProcess? |
| ... | ... |
@@ -61,7 +62,7 @@ type HcsCallback syscall.Handle |
| 61 | 61 |
type HcsProcessInformation struct {
|
| 62 | 62 |
// ProcessId is the pid of the created process. |
| 63 | 63 |
ProcessId uint32 |
| 64 |
- reserved uint32 |
|
| 64 |
+ reserved uint32 //nolint:structcheck |
|
| 65 | 65 |
// StdInput is the handle associated with the stdin of the process. |
| 66 | 66 |
StdInput syscall.Handle |
| 67 | 67 |
// StdOutput is the handle associated with the stdout of the process. |
| ... | ... |
@@ -585,3 +586,25 @@ func HcsUnregisterProcessCallback(ctx gcontext.Context, callbackHandle HcsCallba |
| 585 | 585 |
return hcsUnregisterProcessCallback(callbackHandle) |
| 586 | 586 |
}) |
| 587 | 587 |
} |
| 588 |
+ |
|
| 589 |
+func HcsSaveComputeSystem(ctx gcontext.Context, computeSystem HcsSystem, options string) (result string, hr error) {
|
|
| 590 |
+ ctx, span := trace.StartSpan(ctx, "HcsSaveComputeSystem") |
|
| 591 |
+ defer span.End() |
|
| 592 |
+ defer func() {
|
|
| 593 |
+ if result != "" {
|
|
| 594 |
+ span.AddAttributes(trace.StringAttribute("result", result))
|
|
| 595 |
+ } |
|
| 596 |
+ if hr != errVmcomputeOperationPending {
|
|
| 597 |
+ oc.SetSpanStatus(span, hr) |
|
| 598 |
+ } |
|
| 599 |
+ }() |
|
| 600 |
+ |
|
| 601 |
+ return result, execute(ctx, timeout.SyscallWatcher, func() error {
|
|
| 602 |
+ var resultp *uint16 |
|
| 603 |
+ err := hcsSaveComputeSystem(computeSystem, options, &resultp) |
|
| 604 |
+ if resultp != nil {
|
|
| 605 |
+ result = interop.ConvertAndFreeCoTaskMemString(resultp) |
|
| 606 |
+ } |
|
| 607 |
+ return err |
|
| 608 |
+ }) |
|
| 609 |
+} |
| ... | ... |
@@ -53,6 +53,7 @@ var ( |
| 53 | 53 |
procHcsModifyServiceSettings = modvmcompute.NewProc("HcsModifyServiceSettings")
|
| 54 | 54 |
procHcsRegisterComputeSystemCallback = modvmcompute.NewProc("HcsRegisterComputeSystemCallback")
|
| 55 | 55 |
procHcsUnregisterComputeSystemCallback = modvmcompute.NewProc("HcsUnregisterComputeSystemCallback")
|
| 56 |
+ procHcsSaveComputeSystem = modvmcompute.NewProc("HcsSaveComputeSystem")
|
|
| 56 | 57 |
procHcsCreateProcess = modvmcompute.NewProc("HcsCreateProcess")
|
| 57 | 58 |
procHcsOpenProcess = modvmcompute.NewProc("HcsOpenProcess")
|
| 58 | 59 |
procHcsCloseProcess = modvmcompute.NewProc("HcsCloseProcess")
|
| ... | ... |
@@ -366,6 +367,29 @@ func hcsUnregisterComputeSystemCallback(callbackHandle HcsCallback) (hr error) {
|
| 366 | 366 |
return |
| 367 | 367 |
} |
| 368 | 368 |
|
| 369 |
+func hcsSaveComputeSystem(computeSystem HcsSystem, options string, result **uint16) (hr error) {
|
|
| 370 |
+ var _p0 *uint16 |
|
| 371 |
+ _p0, hr = syscall.UTF16PtrFromString(options) |
|
| 372 |
+ if hr != nil {
|
|
| 373 |
+ return |
|
| 374 |
+ } |
|
| 375 |
+ return _hcsSaveComputeSystem(computeSystem, _p0, result) |
|
| 376 |
+} |
|
| 377 |
+ |
|
| 378 |
+func _hcsSaveComputeSystem(computeSystem HcsSystem, options *uint16, result **uint16) (hr error) {
|
|
| 379 |
+ if hr = procHcsSaveComputeSystem.Find(); hr != nil {
|
|
| 380 |
+ return |
|
| 381 |
+ } |
|
| 382 |
+ r0, _, _ := syscall.Syscall(procHcsSaveComputeSystem.Addr(), 3, uintptr(computeSystem), uintptr(unsafe.Pointer(options)), uintptr(unsafe.Pointer(result))) |
|
| 383 |
+ if int32(r0) < 0 {
|
|
| 384 |
+ if r0&0x1fff0000 == 0x00070000 {
|
|
| 385 |
+ r0 &= 0xffff |
|
| 386 |
+ } |
|
| 387 |
+ hr = syscall.Errno(r0) |
|
| 388 |
+ } |
|
| 389 |
+ return |
|
| 390 |
+} |
|
| 391 |
+ |
|
| 369 | 392 |
func hcsCreateProcess(computeSystem HcsSystem, processParameters string, processInformation *HcsProcessInformation, process *HcsProcess, result **uint16) (hr error) {
|
| 370 | 393 |
var _p0 *uint16 |
| 371 | 394 |
_p0, hr = syscall.UTF16PtrFromString(processParameters) |
| ... | ... |
@@ -14,7 +14,7 @@ import ( |
| 14 | 14 |
// An activated layer must later be deactivated via DeactivateLayer. |
| 15 | 15 |
func ActivateLayer(ctx context.Context, path string) (err error) {
|
| 16 | 16 |
title := "hcsshim::ActivateLayer" |
| 17 |
- ctx, span := trace.StartSpan(ctx, title) |
|
| 17 |
+ ctx, span := trace.StartSpan(ctx, title) //nolint:ineffassign,staticcheck |
|
| 18 | 18 |
defer span.End() |
| 19 | 19 |
defer func() { oc.SetSpanStatus(span, err) }()
|
| 20 | 20 |
span.AddAttributes(trace.StringAttribute("path", path))
|
| ... | ... |
@@ -12,7 +12,7 @@ import ( |
| 12 | 12 |
// the parent layer provided. |
| 13 | 13 |
func CreateLayer(ctx context.Context, path, parent string) (err error) {
|
| 14 | 14 |
title := "hcsshim::CreateLayer" |
| 15 |
- ctx, span := trace.StartSpan(ctx, title) |
|
| 15 |
+ ctx, span := trace.StartSpan(ctx, title) //nolint:ineffassign,staticcheck |
|
| 16 | 16 |
defer span.End() |
| 17 | 17 |
defer func() { oc.SetSpanStatus(span, err) }()
|
| 18 | 18 |
span.AddAttributes( |
| ... | ... |
@@ -11,7 +11,7 @@ import ( |
| 11 | 11 |
// DeactivateLayer will dismount a layer that was mounted via ActivateLayer. |
| 12 | 12 |
func DeactivateLayer(ctx context.Context, path string) (err error) {
|
| 13 | 13 |
title := "hcsshim::DeactivateLayer" |
| 14 |
- ctx, span := trace.StartSpan(ctx, title) |
|
| 14 |
+ ctx, span := trace.StartSpan(ctx, title) //nolint:ineffassign,staticcheck |
|
| 15 | 15 |
defer span.End() |
| 16 | 16 |
defer func() { oc.SetSpanStatus(span, err) }()
|
| 17 | 17 |
span.AddAttributes(trace.StringAttribute("path", path))
|
| ... | ... |
@@ -12,7 +12,7 @@ import ( |
| 12 | 12 |
// path, including that layer's containing folder, if any. |
| 13 | 13 |
func DestroyLayer(ctx context.Context, path string) (err error) {
|
| 14 | 14 |
title := "hcsshim::DestroyLayer" |
| 15 |
- ctx, span := trace.StartSpan(ctx, title) |
|
| 15 |
+ ctx, span := trace.StartSpan(ctx, title) //nolint:ineffassign,staticcheck |
|
| 16 | 16 |
defer span.End() |
| 17 | 17 |
defer func() { oc.SetSpanStatus(span, err) }()
|
| 18 | 18 |
span.AddAttributes(trace.StringAttribute("path", path))
|
| ... | ... |
@@ -21,8 +21,7 @@ func GetLayerMountPath(ctx context.Context, path string) (_ string, err error) {
|
| 21 | 21 |
defer func() { oc.SetSpanStatus(span, err) }()
|
| 22 | 22 |
span.AddAttributes(trace.StringAttribute("path", path))
|
| 23 | 23 |
|
| 24 |
- var mountPathLength uintptr |
|
| 25 |
- mountPathLength = 0 |
|
| 24 |
+ var mountPathLength uintptr = 0 |
|
| 26 | 25 |
|
| 27 | 26 |
// Call the procedure itself. |
| 28 | 27 |
log.G(ctx).Debug("Calling proc (1)")
|
| ... | ... |
@@ -14,7 +14,7 @@ import ( |
| 14 | 14 |
// of registering them with the graphdriver, graph, and tagstore. |
| 15 | 15 |
func GetSharedBaseImages(ctx context.Context) (_ string, err error) {
|
| 16 | 16 |
title := "hcsshim::GetSharedBaseImages" |
| 17 |
- ctx, span := trace.StartSpan(ctx, title) |
|
| 17 |
+ ctx, span := trace.StartSpan(ctx, title) //nolint:ineffassign,staticcheck |
|
| 18 | 18 |
defer span.End() |
| 19 | 19 |
defer func() { oc.SetSpanStatus(span, err) }()
|
| 20 | 20 |
|
| ... | ... |
@@ -11,7 +11,7 @@ import ( |
| 11 | 11 |
// GrantVmAccess adds access to a file for a given VM |
| 12 | 12 |
func GrantVmAccess(ctx context.Context, vmid string, filepath string) (err error) {
|
| 13 | 13 |
title := "hcsshim::GrantVmAccess" |
| 14 |
- ctx, span := trace.StartSpan(ctx, title) |
|
| 14 |
+ ctx, span := trace.StartSpan(ctx, title) //nolint:ineffassign,staticcheck |
|
| 15 | 15 |
defer span.End() |
| 16 | 16 |
defer func() { oc.SetSpanStatus(span, err) }()
|
| 17 | 17 |
span.AddAttributes( |
| ... | ... |
@@ -12,7 +12,7 @@ import ( |
| 12 | 12 |
// to the system. |
| 13 | 13 |
func LayerExists(ctx context.Context, path string) (_ bool, err error) {
|
| 14 | 14 |
title := "hcsshim::LayerExists" |
| 15 |
- ctx, span := trace.StartSpan(ctx, title) |
|
| 15 |
+ ctx, span := trace.StartSpan(ctx, title) //nolint:ineffassign,staticcheck |
|
| 16 | 16 |
defer span.End() |
| 17 | 17 |
defer func() { oc.SetSpanStatus(span, err) }()
|
| 18 | 18 |
span.AddAttributes(trace.StringAttribute("path", path))
|
| ... | ... |
@@ -390,7 +390,7 @@ func (w *legacyLayerWriter) CloseRoots() {
|
| 390 | 390 |
w.destRoot = nil |
| 391 | 391 |
} |
| 392 | 392 |
for i := range w.parentRoots {
|
| 393 |
- w.parentRoots[i].Close() |
|
| 393 |
+ _ = w.parentRoots[i].Close() |
|
| 394 | 394 |
} |
| 395 | 395 |
w.parentRoots = nil |
| 396 | 396 |
} |
| ... | ... |
@@ -640,7 +640,7 @@ func (w *legacyLayerWriter) Add(name string, fileInfo *winio.FileBasicInfo) erro |
| 640 | 640 |
defer func() {
|
| 641 | 641 |
if f != nil {
|
| 642 | 642 |
f.Close() |
| 643 |
- safefile.RemoveRelative(name, w.destRoot) |
|
| 643 |
+ _ = safefile.RemoveRelative(name, w.destRoot) |
|
| 644 | 644 |
} |
| 645 | 645 |
}() |
| 646 | 646 |
|
| ... | ... |
@@ -676,7 +676,7 @@ func (w *legacyLayerWriter) Add(name string, fileInfo *winio.FileBasicInfo) erro |
| 676 | 676 |
defer func() {
|
| 677 | 677 |
if f != nil {
|
| 678 | 678 |
f.Close() |
| 679 |
- safefile.RemoveRelative(fname, w.root) |
|
| 679 |
+ _ = safefile.RemoveRelative(fname, w.root) |
|
| 680 | 680 |
} |
| 681 | 681 |
}() |
| 682 | 682 |
|
| ... | ... |
@@ -14,7 +14,7 @@ import ( |
| 14 | 14 |
// across all clients. |
| 15 | 15 |
func NameToGuid(ctx context.Context, name string) (_ guid.GUID, err error) {
|
| 16 | 16 |
title := "hcsshim::NameToGuid" |
| 17 |
- ctx, span := trace.StartSpan(ctx, title) |
|
| 17 |
+ ctx, span := trace.StartSpan(ctx, title) //nolint:ineffassign,staticcheck |
|
| 18 | 18 |
defer span.End() |
| 19 | 19 |
defer func() { oc.SetSpanStatus(span, err) }()
|
| 20 | 20 |
span.AddAttributes(trace.StringAttribute("name", name))
|
| ... | ... |
@@ -12,7 +12,7 @@ import ( |
| 12 | 12 |
// The files should have been extracted to <path>\Files. |
| 13 | 13 |
func ProcessBaseLayer(ctx context.Context, path string) (err error) {
|
| 14 | 14 |
title := "hcsshim::ProcessBaseLayer" |
| 15 |
- ctx, span := trace.StartSpan(ctx, title) |
|
| 15 |
+ ctx, span := trace.StartSpan(ctx, title) //nolint:ineffassign,staticcheck |
|
| 16 | 16 |
defer span.End() |
| 17 | 17 |
defer func() { oc.SetSpanStatus(span, err) }()
|
| 18 | 18 |
span.AddAttributes(trace.StringAttribute("path", path))
|
| ... | ... |
@@ -28,7 +28,7 @@ func ProcessBaseLayer(ctx context.Context, path string) (err error) {
|
| 28 | 28 |
// The files should have been extracted to <path>\Files. |
| 29 | 29 |
func ProcessUtilityVMImage(ctx context.Context, path string) (err error) {
|
| 30 | 30 |
title := "hcsshim::ProcessUtilityVMImage" |
| 31 |
- ctx, span := trace.StartSpan(ctx, title) |
|
| 31 |
+ ctx, span := trace.StartSpan(ctx, title) //nolint:ineffassign,staticcheck |
|
| 32 | 32 |
defer span.End() |
| 33 | 33 |
defer func() { oc.SetSpanStatus(span, err) }()
|
| 34 | 34 |
span.AddAttributes(trace.StringAttribute("path", path))
|
| ... | ... |
@@ -12,7 +12,7 @@ import ( |
| 12 | 12 |
// the given id. |
| 13 | 13 |
func UnprepareLayer(ctx context.Context, path string) (err error) {
|
| 14 | 14 |
title := "hcsshim::UnprepareLayer" |
| 15 |
- ctx, span := trace.StartSpan(ctx, title) |
|
| 15 |
+ ctx, span := trace.StartSpan(ctx, title) //nolint:ineffassign,staticcheck |
|
| 16 | 16 |
defer span.End() |
| 17 | 17 |
defer func() { oc.SetSpanStatus(span, err) }()
|
| 18 | 18 |
span.AddAttributes(trace.StringAttribute("path", path))
|
| ... | ... |
@@ -31,6 +31,43 @@ const ( |
| 31 | 31 |
STATUS_NO_MORE_ENTRIES = 0x8000001a |
| 32 | 32 |
) |
| 33 | 33 |
|
| 34 |
+// Select entries from FILE_INFO_BY_HANDLE_CLASS. |
|
| 35 |
+// |
|
| 36 |
+// C declaration: |
|
| 37 |
+// typedef enum _FILE_INFO_BY_HANDLE_CLASS {
|
|
| 38 |
+// FileBasicInfo, |
|
| 39 |
+// FileStandardInfo, |
|
| 40 |
+// FileNameInfo, |
|
| 41 |
+// FileRenameInfo, |
|
| 42 |
+// FileDispositionInfo, |
|
| 43 |
+// FileAllocationInfo, |
|
| 44 |
+// FileEndOfFileInfo, |
|
| 45 |
+// FileStreamInfo, |
|
| 46 |
+// FileCompressionInfo, |
|
| 47 |
+// FileAttributeTagInfo, |
|
| 48 |
+// FileIdBothDirectoryInfo, |
|
| 49 |
+// FileIdBothDirectoryRestartInfo, |
|
| 50 |
+// FileIoPriorityHintInfo, |
|
| 51 |
+// FileRemoteProtocolInfo, |
|
| 52 |
+// FileFullDirectoryInfo, |
|
| 53 |
+// FileFullDirectoryRestartInfo, |
|
| 54 |
+// FileStorageInfo, |
|
| 55 |
+// FileAlignmentInfo, |
|
| 56 |
+// FileIdInfo, |
|
| 57 |
+// FileIdExtdDirectoryInfo, |
|
| 58 |
+// FileIdExtdDirectoryRestartInfo, |
|
| 59 |
+// FileDispositionInfoEx, |
|
| 60 |
+// FileRenameInfoEx, |
|
| 61 |
+// FileCaseSensitiveInfo, |
|
| 62 |
+// FileNormalizedNameInfo, |
|
| 63 |
+// MaximumFileInfoByHandleClass |
|
| 64 |
+// } FILE_INFO_BY_HANDLE_CLASS, *PFILE_INFO_BY_HANDLE_CLASS; |
|
| 65 |
+// |
|
| 66 |
+// Documentation: https://docs.microsoft.com/en-us/windows/win32/api/minwinbase/ne-minwinbase-file_info_by_handle_class |
|
| 67 |
+const ( |
|
| 68 |
+ FileIdInfo = 18 |
|
| 69 |
+) |
|
| 70 |
+ |
|
| 34 | 71 |
type FileDispositionInformationEx struct {
|
| 35 | 72 |
Flags uintptr |
| 36 | 73 |
} |
| ... | ... |
@@ -42,7 +79,7 @@ type IOStatusBlock struct {
|
| 42 | 42 |
type ObjectAttributes struct {
|
| 43 | 43 |
Length uintptr |
| 44 | 44 |
RootDirectory uintptr |
| 45 |
- ObjectName uintptr |
|
| 45 |
+ ObjectName *UnicodeString |
|
| 46 | 46 |
Attributes uintptr |
| 47 | 47 |
SecurityDescriptor uintptr |
| 48 | 48 |
SecurityQoS uintptr |
| ... | ... |
@@ -59,3 +96,15 @@ type FileLinkInformation struct {
|
| 59 | 59 |
FileNameLength uint32 |
| 60 | 60 |
FileName [1]uint16 |
| 61 | 61 |
} |
| 62 |
+ |
|
| 63 |
+// C declaration: |
|
| 64 |
+// typedef struct _FILE_ID_INFO {
|
|
| 65 |
+// ULONGLONG VolumeSerialNumber; |
|
| 66 |
+// FILE_ID_128 FileId; |
|
| 67 |
+// } FILE_ID_INFO, *PFILE_ID_INFO; |
|
| 68 |
+// |
|
| 69 |
+// Documentation: https://docs.microsoft.com/en-us/windows/win32/api/winbase/ns-winbase-file_id_info |
|
| 70 |
+type FILE_ID_INFO struct {
|
|
| 71 |
+ VolumeSerialNumber uint64 |
|
| 72 |
+ FileID [16]byte |
|
| 73 |
+} |
| ... | ... |
@@ -1,32 +1,41 @@ |
| 1 | 1 |
package winapi |
| 2 | 2 |
|
| 3 | 3 |
import ( |
| 4 |
+ "unsafe" |
|
| 5 |
+ |
|
| 4 | 6 |
"golang.org/x/sys/windows" |
| 5 | 7 |
) |
| 6 | 8 |
|
| 7 | 9 |
// Messages that can be received from an assigned io completion port. |
| 8 | 10 |
// https://docs.microsoft.com/en-us/windows/win32/api/winnt/ns-winnt-jobobject_associate_completion_port |
| 9 | 11 |
const ( |
| 10 |
- JOB_OBJECT_MSG_END_OF_JOB_TIME = 1 |
|
| 11 |
- JOB_OBJECT_MSG_END_OF_PROCESS_TIME = 2 |
|
| 12 |
- JOB_OBJECT_MSG_ACTIVE_PROCESS_LIMIT = 3 |
|
| 13 |
- JOB_OBJECT_MSG_ACTIVE_PROCESS_ZERO = 4 |
|
| 14 |
- JOB_OBJECT_MSG_NEW_PROCESS = 6 |
|
| 15 |
- JOB_OBJECT_MSG_EXIT_PROCESS = 7 |
|
| 16 |
- JOB_OBJECT_MSG_ABNORMAL_EXIT_PROCESS = 8 |
|
| 17 |
- JOB_OBJECT_MSG_PROCESS_MEMORY_LIMIT = 9 |
|
| 18 |
- JOB_OBJECT_MSG_JOB_MEMORY_LIMIT = 10 |
|
| 19 |
- JOB_OBJECT_MSG_NOTIFICATION_LIMIT = 11 |
|
| 12 |
+ JOB_OBJECT_MSG_END_OF_JOB_TIME uint32 = 1 |
|
| 13 |
+ JOB_OBJECT_MSG_END_OF_PROCESS_TIME uint32 = 2 |
|
| 14 |
+ JOB_OBJECT_MSG_ACTIVE_PROCESS_LIMIT uint32 = 3 |
|
| 15 |
+ JOB_OBJECT_MSG_ACTIVE_PROCESS_ZERO uint32 = 4 |
|
| 16 |
+ JOB_OBJECT_MSG_NEW_PROCESS uint32 = 6 |
|
| 17 |
+ JOB_OBJECT_MSG_EXIT_PROCESS uint32 = 7 |
|
| 18 |
+ JOB_OBJECT_MSG_ABNORMAL_EXIT_PROCESS uint32 = 8 |
|
| 19 |
+ JOB_OBJECT_MSG_PROCESS_MEMORY_LIMIT uint32 = 9 |
|
| 20 |
+ JOB_OBJECT_MSG_JOB_MEMORY_LIMIT uint32 = 10 |
|
| 21 |
+ JOB_OBJECT_MSG_NOTIFICATION_LIMIT uint32 = 11 |
|
| 20 | 22 |
) |
| 21 | 23 |
|
| 24 |
+// Access rights for creating or opening job objects. |
|
| 25 |
+// |
|
| 26 |
+// https://docs.microsoft.com/en-us/windows/win32/procthread/job-object-security-and-access-rights |
|
| 27 |
+const JOB_OBJECT_ALL_ACCESS = 0x1F001F |
|
| 28 |
+ |
|
| 22 | 29 |
// IO limit flags |
| 23 | 30 |
// |
| 24 | 31 |
// https://docs.microsoft.com/en-us/windows/win32/api/jobapi2/ns-jobapi2-jobobject_io_rate_control_information |
| 25 | 32 |
const JOB_OBJECT_IO_RATE_CONTROL_ENABLE = 0x1 |
| 26 | 33 |
|
| 34 |
+const JOBOBJECT_IO_ATTRIBUTION_CONTROL_ENABLE uint32 = 0x1 |
|
| 35 |
+ |
|
| 27 | 36 |
// https://docs.microsoft.com/en-us/windows/win32/api/winnt/ns-winnt-jobobject_cpu_rate_control_information |
| 28 | 37 |
const ( |
| 29 |
- JOB_OBJECT_CPU_RATE_CONTROL_ENABLE = 1 << iota |
|
| 38 |
+ JOB_OBJECT_CPU_RATE_CONTROL_ENABLE uint32 = 1 << iota |
|
| 30 | 39 |
JOB_OBJECT_CPU_RATE_CONTROL_WEIGHT_BASED |
| 31 | 40 |
JOB_OBJECT_CPU_RATE_CONTROL_HARD_CAP |
| 32 | 41 |
JOB_OBJECT_CPU_RATE_CONTROL_NOTIFY |
| ... | ... |
@@ -41,7 +50,9 @@ const ( |
| 41 | 41 |
JobObjectBasicProcessIdList uint32 = 3 |
| 42 | 42 |
JobObjectBasicAndIoAccountingInformation uint32 = 8 |
| 43 | 43 |
JobObjectLimitViolationInformation uint32 = 13 |
| 44 |
+ JobObjectMemoryUsageInformation uint32 = 28 |
|
| 44 | 45 |
JobObjectNotificationLimitInformation2 uint32 = 33 |
| 46 |
+ JobObjectIoAttribution uint32 = 42 |
|
| 45 | 47 |
) |
| 46 | 48 |
|
| 47 | 49 |
// https://docs.microsoft.com/en-us/windows/win32/api/winnt/ns-winnt-jobobject_basic_limit_information |
| ... | ... |
@@ -60,7 +71,7 @@ type JOBOBJECT_BASIC_LIMIT_INFORMATION struct {
|
| 60 | 60 |
// https://docs.microsoft.com/en-us/windows/win32/api/winnt/ns-winnt-jobobject_cpu_rate_control_information |
| 61 | 61 |
type JOBOBJECT_CPU_RATE_CONTROL_INFORMATION struct {
|
| 62 | 62 |
ControlFlags uint32 |
| 63 |
- Rate uint32 |
|
| 63 |
+ Value uint32 |
|
| 64 | 64 |
} |
| 65 | 65 |
|
| 66 | 66 |
// https://docs.microsoft.com/en-us/windows/win32/api/jobapi2/ns-jobapi2-jobobject_io_rate_control_information |
| ... | ... |
@@ -80,9 +91,68 @@ type JOBOBJECT_BASIC_PROCESS_ID_LIST struct {
|
| 80 | 80 |
ProcessIdList [1]uintptr |
| 81 | 81 |
} |
| 82 | 82 |
|
| 83 |
+// AllPids returns all the process Ids in the job object. |
|
| 84 |
+func (p *JOBOBJECT_BASIC_PROCESS_ID_LIST) AllPids() []uintptr {
|
|
| 85 |
+ return (*[(1 << 27) - 1]uintptr)(unsafe.Pointer(&p.ProcessIdList[0]))[:p.NumberOfProcessIdsInList] |
|
| 86 |
+} |
|
| 87 |
+ |
|
| 88 |
+// https://docs.microsoft.com/en-us/windows/win32/api/winnt/ns-winnt-jobobject_basic_accounting_information |
|
| 89 |
+type JOBOBJECT_BASIC_ACCOUNTING_INFORMATION struct {
|
|
| 90 |
+ TotalUserTime int64 |
|
| 91 |
+ TotalKernelTime int64 |
|
| 92 |
+ ThisPeriodTotalUserTime int64 |
|
| 93 |
+ ThisPeriodTotalKernelTime int64 |
|
| 94 |
+ TotalPageFaultCount uint32 |
|
| 95 |
+ TotalProcesses uint32 |
|
| 96 |
+ ActiveProcesses uint32 |
|
| 97 |
+ TotalTerminateProcesses uint32 |
|
| 98 |
+} |
|
| 99 |
+ |
|
| 100 |
+//https://docs.microsoft.com/en-us/windows/win32/api/winnt/ns-winnt-jobobject_basic_and_io_accounting_information |
|
| 101 |
+type JOBOBJECT_BASIC_AND_IO_ACCOUNTING_INFORMATION struct {
|
|
| 102 |
+ BasicInfo JOBOBJECT_BASIC_ACCOUNTING_INFORMATION |
|
| 103 |
+ IoInfo windows.IO_COUNTERS |
|
| 104 |
+} |
|
| 105 |
+ |
|
| 106 |
+// typedef struct _JOBOBJECT_MEMORY_USAGE_INFORMATION {
|
|
| 107 |
+// ULONG64 JobMemory; |
|
| 108 |
+// ULONG64 PeakJobMemoryUsed; |
|
| 109 |
+// } JOBOBJECT_MEMORY_USAGE_INFORMATION, *PJOBOBJECT_MEMORY_USAGE_INFORMATION; |
|
| 110 |
+// |
|
| 111 |
+type JOBOBJECT_MEMORY_USAGE_INFORMATION struct {
|
|
| 112 |
+ JobMemory uint64 |
|
| 113 |
+ PeakJobMemoryUsed uint64 |
|
| 114 |
+} |
|
| 115 |
+ |
|
| 116 |
+// typedef struct _JOBOBJECT_IO_ATTRIBUTION_STATS {
|
|
| 117 |
+// ULONG_PTR IoCount; |
|
| 118 |
+// ULONGLONG TotalNonOverlappedQueueTime; |
|
| 119 |
+// ULONGLONG TotalNonOverlappedServiceTime; |
|
| 120 |
+// ULONGLONG TotalSize; |
|
| 121 |
+// } JOBOBJECT_IO_ATTRIBUTION_STATS, *PJOBOBJECT_IO_ATTRIBUTION_STATS; |
|
| 122 |
+// |
|
| 123 |
+type JOBOBJECT_IO_ATTRIBUTION_STATS struct {
|
|
| 124 |
+ IoCount uintptr |
|
| 125 |
+ TotalNonOverlappedQueueTime uint64 |
|
| 126 |
+ TotalNonOverlappedServiceTime uint64 |
|
| 127 |
+ TotalSize uint64 |
|
| 128 |
+} |
|
| 129 |
+ |
|
| 130 |
+// typedef struct _JOBOBJECT_IO_ATTRIBUTION_INFORMATION {
|
|
| 131 |
+// ULONG ControlFlags; |
|
| 132 |
+// JOBOBJECT_IO_ATTRIBUTION_STATS ReadStats; |
|
| 133 |
+// JOBOBJECT_IO_ATTRIBUTION_STATS WriteStats; |
|
| 134 |
+// } JOBOBJECT_IO_ATTRIBUTION_INFORMATION, *PJOBOBJECT_IO_ATTRIBUTION_INFORMATION; |
|
| 135 |
+// |
|
| 136 |
+type JOBOBJECT_IO_ATTRIBUTION_INFORMATION struct {
|
|
| 137 |
+ ControlFlags uint32 |
|
| 138 |
+ ReadStats JOBOBJECT_IO_ATTRIBUTION_STATS |
|
| 139 |
+ WriteStats JOBOBJECT_IO_ATTRIBUTION_STATS |
|
| 140 |
+} |
|
| 141 |
+ |
|
| 83 | 142 |
// https://docs.microsoft.com/en-us/windows/win32/api/winnt/ns-winnt-jobobject_associate_completion_port |
| 84 | 143 |
type JOBOBJECT_ASSOCIATE_COMPLETION_PORT struct {
|
| 85 |
- CompletionKey uintptr |
|
| 144 |
+ CompletionKey windows.Handle |
|
| 86 | 145 |
CompletionPort windows.Handle |
| 87 | 146 |
} |
| 88 | 147 |
|
| ... | ... |
@@ -118,3 +188,28 @@ type JOBOBJECT_ASSOCIATE_COMPLETION_PORT struct {
|
| 118 | 118 |
// ); |
| 119 | 119 |
// |
| 120 | 120 |
//sys SetIoRateControlInformationJobObject(jobHandle windows.Handle, ioRateControlInfo *JOBOBJECT_IO_RATE_CONTROL_INFORMATION) (ret uint32, err error) = kernel32.SetIoRateControlInformationJobObject |
| 121 |
+ |
|
| 122 |
+// DWORD QueryIoRateControlInformationJobObject( |
|
| 123 |
+// HANDLE hJob, |
|
| 124 |
+// PCWSTR VolumeName, |
|
| 125 |
+// JOBOBJECT_IO_RATE_CONTROL_INFORMATION **InfoBlocks, |
|
| 126 |
+// ULONG *InfoBlockCount |
|
| 127 |
+// ); |
|
| 128 |
+//sys QueryIoRateControlInformationJobObject(jobHandle windows.Handle, volumeName *uint16, ioRateControlInfo **JOBOBJECT_IO_RATE_CONTROL_INFORMATION, infoBlockCount *uint32) (ret uint32, err error) = kernel32.QueryIoRateControlInformationJobObject |
|
| 129 |
+ |
|
| 130 |
+// NTSTATUS |
|
| 131 |
+// NtOpenJobObject ( |
|
| 132 |
+// _Out_ PHANDLE JobHandle, |
|
| 133 |
+// _In_ ACCESS_MASK DesiredAccess, |
|
| 134 |
+// _In_ POBJECT_ATTRIBUTES ObjectAttributes |
|
| 135 |
+// ); |
|
| 136 |
+//sys NtOpenJobObject(jobHandle *windows.Handle, desiredAccess uint32, objAttributes *ObjectAttributes) (status uint32) = ntdll.NtOpenJobObject |
|
| 137 |
+ |
|
| 138 |
+// NTSTATUS |
|
| 139 |
+// NTAPI |
|
| 140 |
+// NtCreateJobObject ( |
|
| 141 |
+// _Out_ PHANDLE JobHandle, |
|
| 142 |
+// _In_ ACCESS_MASK DesiredAccess, |
|
| 143 |
+// _In_opt_ POBJECT_ATTRIBUTES ObjectAttributes |
|
| 144 |
+// ); |
|
| 145 |
+//sys NtCreateJobObject(jobHandle *windows.Handle, desiredAccess uint32, objAttributes *ObjectAttributes) (status uint32) = ntdll.NtCreateJobObject |
| ... | ... |
@@ -9,3 +9,19 @@ package winapi |
| 9 | 9 |
|
| 10 | 10 |
//sys LocalAlloc(flags uint32, size int) (ptr uintptr) = kernel32.LocalAlloc |
| 11 | 11 |
//sys LocalFree(ptr uintptr) = kernel32.LocalFree |
| 12 |
+ |
|
| 13 |
+// BOOL QueryWorkingSet( |
|
| 14 |
+// HANDLE hProcess, |
|
| 15 |
+// PVOID pv, |
|
| 16 |
+// DWORD cb |
|
| 17 |
+// ); |
|
| 18 |
+//sys QueryWorkingSet(handle windows.Handle, pv uintptr, cb uint32) (err error) = psapi.QueryWorkingSet |
|
| 19 |
+ |
|
| 20 |
+type PSAPI_WORKING_SET_INFORMATION struct {
|
|
| 21 |
+ NumberOfEntries uintptr |
|
| 22 |
+ WorkingSetInfo [1]PSAPI_WORKING_SET_BLOCK |
|
| 23 |
+} |
|
| 24 |
+ |
|
| 25 |
+type PSAPI_WORKING_SET_BLOCK struct {
|
|
| 26 |
+ Flags uintptr |
|
| 27 |
+} |
| ... | ... |
@@ -8,4 +8,4 @@ package winapi |
| 8 | 8 |
// LPWSTR lpBuffer, |
| 9 | 9 |
// LPWSTR *lpFilePart |
| 10 | 10 |
// ); |
| 11 |
-//sys SearchPath(lpPath *uint16, lpFileName *uint16, lpExtension *uint16, nBufferLength uint32, lpBuffer *uint16, lpFilePath **uint16) (size uint32, err error) = kernel32.SearchPathW |
|
| 11 |
+//sys SearchPath(lpPath *uint16, lpFileName *uint16, lpExtension *uint16, nBufferLength uint32, lpBuffer *uint16, lpFilePath *uint16) (size uint32, err error) = kernel32.SearchPathW |
| ... | ... |
@@ -1,3 +1,10 @@ |
| 1 | 1 |
package winapi |
| 2 | 2 |
|
| 3 | 3 |
const PROCESS_ALL_ACCESS uint32 = 2097151 |
| 4 |
+ |
|
| 5 |
+// DWORD GetProcessImageFileNameW( |
|
| 6 |
+// HANDLE hProcess, |
|
| 7 |
+// LPWSTR lpImageFileName, |
|
| 8 |
+// DWORD nSize |
|
| 9 |
+// ); |
|
| 10 |
+//sys GetProcessImageFileName(hProcess windows.Handle, imageFileName *uint16, nSize uint32) (size uint32, err error) = kernel32.GetProcessImageFileNameW |
| 4 | 11 |
new file mode 100644 |
| ... | ... |
@@ -0,0 +1,52 @@ |
| 0 |
+package winapi |
|
| 1 |
+ |
|
| 2 |
+import "golang.org/x/sys/windows" |
|
| 3 |
+ |
|
| 4 |
+const SystemProcessInformation = 5 |
|
| 5 |
+ |
|
| 6 |
+const STATUS_INFO_LENGTH_MISMATCH = 0xC0000004 |
|
| 7 |
+ |
|
| 8 |
+// __kernel_entry NTSTATUS NtQuerySystemInformation( |
|
| 9 |
+// SYSTEM_INFORMATION_CLASS SystemInformationClass, |
|
| 10 |
+// PVOID SystemInformation, |
|
| 11 |
+// ULONG SystemInformationLength, |
|
| 12 |
+// PULONG ReturnLength |
|
| 13 |
+// ); |
|
| 14 |
+//sys NtQuerySystemInformation(systemInfoClass int, systemInformation uintptr, systemInfoLength uint32, returnLength *uint32) (status uint32) = ntdll.NtQuerySystemInformation |
|
| 15 |
+ |
|
| 16 |
+type SYSTEM_PROCESS_INFORMATION struct {
|
|
| 17 |
+ NextEntryOffset uint32 // ULONG |
|
| 18 |
+ NumberOfThreads uint32 // ULONG |
|
| 19 |
+ WorkingSetPrivateSize int64 // LARGE_INTEGER |
|
| 20 |
+ HardFaultCount uint32 // ULONG |
|
| 21 |
+ NumberOfThreadsHighWatermark uint32 // ULONG |
|
| 22 |
+ CycleTime uint64 // ULONGLONG |
|
| 23 |
+ CreateTime int64 // LARGE_INTEGER |
|
| 24 |
+ UserTime int64 // LARGE_INTEGER |
|
| 25 |
+ KernelTime int64 // LARGE_INTEGER |
|
| 26 |
+ ImageName UnicodeString // UNICODE_STRING |
|
| 27 |
+ BasePriority int32 // KPRIORITY |
|
| 28 |
+ UniqueProcessID windows.Handle // HANDLE |
|
| 29 |
+ InheritedFromUniqueProcessID windows.Handle // HANDLE |
|
| 30 |
+ HandleCount uint32 // ULONG |
|
| 31 |
+ SessionID uint32 // ULONG |
|
| 32 |
+ UniqueProcessKey *uint32 // ULONG_PTR |
|
| 33 |
+ PeakVirtualSize uintptr // SIZE_T |
|
| 34 |
+ VirtualSize uintptr // SIZE_T |
|
| 35 |
+ PageFaultCount uint32 // ULONG |
|
| 36 |
+ PeakWorkingSetSize uintptr // SIZE_T |
|
| 37 |
+ WorkingSetSize uintptr // SIZE_T |
|
| 38 |
+ QuotaPeakPagedPoolUsage uintptr // SIZE_T |
|
| 39 |
+ QuotaPagedPoolUsage uintptr // SIZE_T |
|
| 40 |
+ QuotaPeakNonPagedPoolUsage uintptr // SIZE_T |
|
| 41 |
+ QuotaNonPagedPoolUsage uintptr // SIZE_T |
|
| 42 |
+ PagefileUsage uintptr // SIZE_T |
|
| 43 |
+ PeakPagefileUsage uintptr // SIZE_T |
|
| 44 |
+ PrivatePageCount uintptr // SIZE_T |
|
| 45 |
+ ReadOperationCount int64 // LARGE_INTEGER |
|
| 46 |
+ WriteOperationCount int64 // LARGE_INTEGER |
|
| 47 |
+ OtherOperationCount int64 // LARGE_INTEGER |
|
| 48 |
+ ReadTransferCount int64 // LARGE_INTEGER |
|
| 49 |
+ WriteTransferCount int64 // LARGE_INTEGER |
|
| 50 |
+ OtherTransferCount int64 // LARGE_INTEGER |
|
| 51 |
+} |
| 0 | 52 |
new file mode 100644 |
| ... | ... |
@@ -0,0 +1,12 @@ |
| 0 |
+package winapi |
|
| 1 |
+ |
|
| 2 |
+// HANDLE CreateRemoteThread( |
|
| 3 |
+// HANDLE hProcess, |
|
| 4 |
+// LPSECURITY_ATTRIBUTES lpThreadAttributes, |
|
| 5 |
+// SIZE_T dwStackSize, |
|
| 6 |
+// LPTHREAD_START_ROUTINE lpStartAddress, |
|
| 7 |
+// LPVOID lpParameter, |
|
| 8 |
+// DWORD dwCreationFlags, |
|
| 9 |
+// LPDWORD lpThreadId |
|
| 10 |
+// ); |
|
| 11 |
+//sys CreateRemoteThread(process windows.Handle, sa *windows.SecurityAttributes, stackSize uint32, startAddr uintptr, parameter uintptr, creationFlags uint32, threadID *uint32) (handle windows.Handle, err error) = kernel32.CreateRemoteThread |
| ... | ... |
@@ -2,11 +2,24 @@ package winapi |
| 2 | 2 |
|
| 3 | 3 |
import ( |
| 4 | 4 |
"errors" |
| 5 |
+ "reflect" |
|
| 5 | 6 |
"syscall" |
| 6 |
- "unicode/utf16" |
|
| 7 | 7 |
"unsafe" |
| 8 |
+ |
|
| 9 |
+ "golang.org/x/sys/windows" |
|
| 8 | 10 |
) |
| 9 | 11 |
|
| 12 |
+// Uint16BufferToSlice wraps a uint16 pointer-and-length into a slice |
|
| 13 |
+// for easier interop with Go APIs |
|
| 14 |
+func Uint16BufferToSlice(buffer *uint16, bufferLength int) (result []uint16) {
|
|
| 15 |
+ hdr := (*reflect.SliceHeader)(unsafe.Pointer(&result)) |
|
| 16 |
+ hdr.Data = uintptr(unsafe.Pointer(buffer)) |
|
| 17 |
+ hdr.Cap = bufferLength |
|
| 18 |
+ hdr.Len = bufferLength |
|
| 19 |
+ |
|
| 20 |
+ return |
|
| 21 |
+} |
|
| 22 |
+ |
|
| 10 | 23 |
type UnicodeString struct {
|
| 11 | 24 |
Length uint16 |
| 12 | 25 |
MaximumLength uint16 |
| ... | ... |
@@ -15,28 +28,30 @@ type UnicodeString struct {
|
| 15 | 15 |
|
| 16 | 16 |
//String converts a UnicodeString to a golang string |
| 17 | 17 |
func (uni UnicodeString) String() string {
|
| 18 |
- p := (*[0xffff]uint16)(unsafe.Pointer(uni.Buffer)) |
|
| 19 |
- |
|
| 20 | 18 |
// UnicodeString is not guaranteed to be null terminated, therefore |
| 21 | 19 |
// use the UnicodeString's Length field |
| 22 |
- lengthInChars := uni.Length / 2 |
|
| 23 |
- return syscall.UTF16ToString(p[:lengthInChars]) |
|
| 20 |
+ return syscall.UTF16ToString(Uint16BufferToSlice(uni.Buffer, int(uni.Length/2))) |
|
| 24 | 21 |
} |
| 25 | 22 |
|
| 26 | 23 |
// NewUnicodeString allocates a new UnicodeString and copies `s` into |
| 27 | 24 |
// the buffer of the new UnicodeString. |
| 28 | 25 |
func NewUnicodeString(s string) (*UnicodeString, error) {
|
| 29 |
- ws := utf16.Encode(([]rune)(s)) |
|
| 30 |
- if len(ws) > 32767 {
|
|
| 26 |
+ // Get length of original `s` to use in the UnicodeString since the `buf` |
|
| 27 |
+ // created later will have an additional trailing null character |
|
| 28 |
+ length := len(s) |
|
| 29 |
+ if length > 32767 {
|
|
| 31 | 30 |
return nil, syscall.ENAMETOOLONG |
| 32 | 31 |
} |
| 33 | 32 |
|
| 33 |
+ buf, err := windows.UTF16FromString(s) |
|
| 34 |
+ if err != nil {
|
|
| 35 |
+ return nil, err |
|
| 36 |
+ } |
|
| 34 | 37 |
uni := &UnicodeString{
|
| 35 |
- Length: uint16(len(ws) * 2), |
|
| 36 |
- MaximumLength: uint16(len(ws) * 2), |
|
| 37 |
- Buffer: &make([]uint16, len(ws))[0], |
|
| 38 |
+ Length: uint16(length * 2), |
|
| 39 |
+ MaximumLength: uint16(length * 2), |
|
| 40 |
+ Buffer: &buf[0], |
|
| 38 | 41 |
} |
| 39 |
- copy((*[32768]uint16)(unsafe.Pointer(uni.Buffer))[:], ws) |
|
| 40 | 42 |
return uni, nil |
| 41 | 43 |
} |
| 42 | 44 |
|
| ... | ... |
@@ -2,4 +2,4 @@ |
| 2 | 2 |
// be thought of as an extension to golang.org/x/sys/windows. |
| 3 | 3 |
package winapi |
| 4 | 4 |
|
| 5 |
-//go:generate go run ..\..\mksyscall_windows.go -output zsyscall_windows.go jobobject.go path.go logon.go memory.go processor.go devices.go filesystem.go errors.go |
|
| 5 |
+//go:generate go run ..\..\mksyscall_windows.go -output zsyscall_windows.go system.go net.go path.go thread.go iocp.go jobobject.go logon.go memory.go process.go processor.go devices.go filesystem.go errors.go |
| ... | ... |
@@ -37,32 +37,95 @@ func errnoErr(e syscall.Errno) error {
|
| 37 | 37 |
} |
| 38 | 38 |
|
| 39 | 39 |
var ( |
| 40 |
+ modntdll = windows.NewLazySystemDLL("ntdll.dll")
|
|
| 41 |
+ modiphlpapi = windows.NewLazySystemDLL("iphlpapi.dll")
|
|
| 40 | 42 |
modkernel32 = windows.NewLazySystemDLL("kernel32.dll")
|
| 41 | 43 |
modadvapi32 = windows.NewLazySystemDLL("advapi32.dll")
|
| 44 |
+ modpsapi = windows.NewLazySystemDLL("psapi.dll")
|
|
| 42 | 45 |
modcfgmgr32 = windows.NewLazySystemDLL("cfgmgr32.dll")
|
| 43 |
- modntdll = windows.NewLazySystemDLL("ntdll.dll")
|
|
| 44 | 46 |
|
| 45 |
- procIsProcessInJob = modkernel32.NewProc("IsProcessInJob")
|
|
| 46 |
- procQueryInformationJobObject = modkernel32.NewProc("QueryInformationJobObject")
|
|
| 47 |
- procOpenJobObjectW = modkernel32.NewProc("OpenJobObjectW")
|
|
| 48 |
- procSetIoRateControlInformationJobObject = modkernel32.NewProc("SetIoRateControlInformationJobObject")
|
|
| 49 |
- procSearchPathW = modkernel32.NewProc("SearchPathW")
|
|
| 50 |
- procLogonUserW = modadvapi32.NewProc("LogonUserW")
|
|
| 51 |
- procRtlMoveMemory = modkernel32.NewProc("RtlMoveMemory")
|
|
| 52 |
- procLocalAlloc = modkernel32.NewProc("LocalAlloc")
|
|
| 53 |
- procLocalFree = modkernel32.NewProc("LocalFree")
|
|
| 54 |
- procGetActiveProcessorCount = modkernel32.NewProc("GetActiveProcessorCount")
|
|
| 55 |
- procCM_Get_Device_ID_List_SizeA = modcfgmgr32.NewProc("CM_Get_Device_ID_List_SizeA")
|
|
| 56 |
- procCM_Get_Device_ID_ListA = modcfgmgr32.NewProc("CM_Get_Device_ID_ListA")
|
|
| 57 |
- procCM_Locate_DevNodeW = modcfgmgr32.NewProc("CM_Locate_DevNodeW")
|
|
| 58 |
- procCM_Get_DevNode_PropertyW = modcfgmgr32.NewProc("CM_Get_DevNode_PropertyW")
|
|
| 59 |
- procNtCreateFile = modntdll.NewProc("NtCreateFile")
|
|
| 60 |
- procNtSetInformationFile = modntdll.NewProc("NtSetInformationFile")
|
|
| 61 |
- procNtOpenDirectoryObject = modntdll.NewProc("NtOpenDirectoryObject")
|
|
| 62 |
- procNtQueryDirectoryObject = modntdll.NewProc("NtQueryDirectoryObject")
|
|
| 63 |
- procRtlNtStatusToDosError = modntdll.NewProc("RtlNtStatusToDosError")
|
|
| 47 |
+ procNtQuerySystemInformation = modntdll.NewProc("NtQuerySystemInformation")
|
|
| 48 |
+ procSetJobCompartmentId = modiphlpapi.NewProc("SetJobCompartmentId")
|
|
| 49 |
+ procSearchPathW = modkernel32.NewProc("SearchPathW")
|
|
| 50 |
+ procCreateRemoteThread = modkernel32.NewProc("CreateRemoteThread")
|
|
| 51 |
+ procGetQueuedCompletionStatus = modkernel32.NewProc("GetQueuedCompletionStatus")
|
|
| 52 |
+ procIsProcessInJob = modkernel32.NewProc("IsProcessInJob")
|
|
| 53 |
+ procQueryInformationJobObject = modkernel32.NewProc("QueryInformationJobObject")
|
|
| 54 |
+ procOpenJobObjectW = modkernel32.NewProc("OpenJobObjectW")
|
|
| 55 |
+ procSetIoRateControlInformationJobObject = modkernel32.NewProc("SetIoRateControlInformationJobObject")
|
|
| 56 |
+ procQueryIoRateControlInformationJobObject = modkernel32.NewProc("QueryIoRateControlInformationJobObject")
|
|
| 57 |
+ procNtOpenJobObject = modntdll.NewProc("NtOpenJobObject")
|
|
| 58 |
+ procNtCreateJobObject = modntdll.NewProc("NtCreateJobObject")
|
|
| 59 |
+ procLogonUserW = modadvapi32.NewProc("LogonUserW")
|
|
| 60 |
+ procRtlMoveMemory = modkernel32.NewProc("RtlMoveMemory")
|
|
| 61 |
+ procLocalAlloc = modkernel32.NewProc("LocalAlloc")
|
|
| 62 |
+ procLocalFree = modkernel32.NewProc("LocalFree")
|
|
| 63 |
+ procQueryWorkingSet = modpsapi.NewProc("QueryWorkingSet")
|
|
| 64 |
+ procGetProcessImageFileNameW = modkernel32.NewProc("GetProcessImageFileNameW")
|
|
| 65 |
+ procGetActiveProcessorCount = modkernel32.NewProc("GetActiveProcessorCount")
|
|
| 66 |
+ procCM_Get_Device_ID_List_SizeA = modcfgmgr32.NewProc("CM_Get_Device_ID_List_SizeA")
|
|
| 67 |
+ procCM_Get_Device_ID_ListA = modcfgmgr32.NewProc("CM_Get_Device_ID_ListA")
|
|
| 68 |
+ procCM_Locate_DevNodeW = modcfgmgr32.NewProc("CM_Locate_DevNodeW")
|
|
| 69 |
+ procCM_Get_DevNode_PropertyW = modcfgmgr32.NewProc("CM_Get_DevNode_PropertyW")
|
|
| 70 |
+ procNtCreateFile = modntdll.NewProc("NtCreateFile")
|
|
| 71 |
+ procNtSetInformationFile = modntdll.NewProc("NtSetInformationFile")
|
|
| 72 |
+ procNtOpenDirectoryObject = modntdll.NewProc("NtOpenDirectoryObject")
|
|
| 73 |
+ procNtQueryDirectoryObject = modntdll.NewProc("NtQueryDirectoryObject")
|
|
| 74 |
+ procRtlNtStatusToDosError = modntdll.NewProc("RtlNtStatusToDosError")
|
|
| 64 | 75 |
) |
| 65 | 76 |
|
| 77 |
+func NtQuerySystemInformation(systemInfoClass int, systemInformation uintptr, systemInfoLength uint32, returnLength *uint32) (status uint32) {
|
|
| 78 |
+ r0, _, _ := syscall.Syscall6(procNtQuerySystemInformation.Addr(), 4, uintptr(systemInfoClass), uintptr(systemInformation), uintptr(systemInfoLength), uintptr(unsafe.Pointer(returnLength)), 0, 0) |
|
| 79 |
+ status = uint32(r0) |
|
| 80 |
+ return |
|
| 81 |
+} |
|
| 82 |
+ |
|
| 83 |
+func SetJobCompartmentId(handle windows.Handle, compartmentId uint32) (win32Err error) {
|
|
| 84 |
+ r0, _, _ := syscall.Syscall(procSetJobCompartmentId.Addr(), 2, uintptr(handle), uintptr(compartmentId), 0) |
|
| 85 |
+ if r0 != 0 {
|
|
| 86 |
+ win32Err = syscall.Errno(r0) |
|
| 87 |
+ } |
|
| 88 |
+ return |
|
| 89 |
+} |
|
| 90 |
+ |
|
| 91 |
+func SearchPath(lpPath *uint16, lpFileName *uint16, lpExtension *uint16, nBufferLength uint32, lpBuffer *uint16, lpFilePath *uint16) (size uint32, err error) {
|
|
| 92 |
+ r0, _, e1 := syscall.Syscall6(procSearchPathW.Addr(), 6, uintptr(unsafe.Pointer(lpPath)), uintptr(unsafe.Pointer(lpFileName)), uintptr(unsafe.Pointer(lpExtension)), uintptr(nBufferLength), uintptr(unsafe.Pointer(lpBuffer)), uintptr(unsafe.Pointer(lpFilePath))) |
|
| 93 |
+ size = uint32(r0) |
|
| 94 |
+ if size == 0 {
|
|
| 95 |
+ if e1 != 0 {
|
|
| 96 |
+ err = errnoErr(e1) |
|
| 97 |
+ } else {
|
|
| 98 |
+ err = syscall.EINVAL |
|
| 99 |
+ } |
|
| 100 |
+ } |
|
| 101 |
+ return |
|
| 102 |
+} |
|
| 103 |
+ |
|
| 104 |
+func CreateRemoteThread(process windows.Handle, sa *windows.SecurityAttributes, stackSize uint32, startAddr uintptr, parameter uintptr, creationFlags uint32, threadID *uint32) (handle windows.Handle, err error) {
|
|
| 105 |
+ r0, _, e1 := syscall.Syscall9(procCreateRemoteThread.Addr(), 7, uintptr(process), uintptr(unsafe.Pointer(sa)), uintptr(stackSize), uintptr(startAddr), uintptr(parameter), uintptr(creationFlags), uintptr(unsafe.Pointer(threadID)), 0, 0) |
|
| 106 |
+ handle = windows.Handle(r0) |
|
| 107 |
+ if handle == 0 {
|
|
| 108 |
+ if e1 != 0 {
|
|
| 109 |
+ err = errnoErr(e1) |
|
| 110 |
+ } else {
|
|
| 111 |
+ err = syscall.EINVAL |
|
| 112 |
+ } |
|
| 113 |
+ } |
|
| 114 |
+ return |
|
| 115 |
+} |
|
| 116 |
+ |
|
| 117 |
+func GetQueuedCompletionStatus(cphandle windows.Handle, qty *uint32, key *uintptr, overlapped **windows.Overlapped, timeout uint32) (err error) {
|
|
| 118 |
+ r1, _, e1 := syscall.Syscall6(procGetQueuedCompletionStatus.Addr(), 5, uintptr(cphandle), uintptr(unsafe.Pointer(qty)), uintptr(unsafe.Pointer(key)), uintptr(unsafe.Pointer(overlapped)), uintptr(timeout), 0) |
|
| 119 |
+ if r1 == 0 {
|
|
| 120 |
+ if e1 != 0 {
|
|
| 121 |
+ err = errnoErr(e1) |
|
| 122 |
+ } else {
|
|
| 123 |
+ err = syscall.EINVAL |
|
| 124 |
+ } |
|
| 125 |
+ } |
|
| 126 |
+ return |
|
| 127 |
+} |
|
| 128 |
+ |
|
| 66 | 129 |
func IsProcessInJob(procHandle windows.Handle, jobHandle windows.Handle, result *bool) (err error) {
|
| 67 | 130 |
r1, _, e1 := syscall.Syscall(procIsProcessInJob.Addr(), 3, uintptr(procHandle), uintptr(jobHandle), uintptr(unsafe.Pointer(result))) |
| 68 | 131 |
if r1 == 0 {
|
| ... | ... |
@@ -119,10 +182,10 @@ func SetIoRateControlInformationJobObject(jobHandle windows.Handle, ioRateContro |
| 119 | 119 |
return |
| 120 | 120 |
} |
| 121 | 121 |
|
| 122 |
-func SearchPath(lpPath *uint16, lpFileName *uint16, lpExtension *uint16, nBufferLength uint32, lpBuffer *uint16, lpFilePath **uint16) (size uint32, err error) {
|
|
| 123 |
- r0, _, e1 := syscall.Syscall6(procSearchPathW.Addr(), 6, uintptr(unsafe.Pointer(lpPath)), uintptr(unsafe.Pointer(lpFileName)), uintptr(unsafe.Pointer(lpExtension)), uintptr(nBufferLength), uintptr(unsafe.Pointer(lpBuffer)), uintptr(unsafe.Pointer(lpFilePath))) |
|
| 124 |
- size = uint32(r0) |
|
| 125 |
- if size == 0 {
|
|
| 122 |
+func QueryIoRateControlInformationJobObject(jobHandle windows.Handle, volumeName *uint16, ioRateControlInfo **JOBOBJECT_IO_RATE_CONTROL_INFORMATION, infoBlockCount *uint32) (ret uint32, err error) {
|
|
| 123 |
+ r0, _, e1 := syscall.Syscall6(procQueryIoRateControlInformationJobObject.Addr(), 4, uintptr(jobHandle), uintptr(unsafe.Pointer(volumeName)), uintptr(unsafe.Pointer(ioRateControlInfo)), uintptr(unsafe.Pointer(infoBlockCount)), 0, 0) |
|
| 124 |
+ ret = uint32(r0) |
|
| 125 |
+ if ret == 0 {
|
|
| 126 | 126 |
if e1 != 0 {
|
| 127 | 127 |
err = errnoErr(e1) |
| 128 | 128 |
} else {
|
| ... | ... |
@@ -132,6 +195,18 @@ func SearchPath(lpPath *uint16, lpFileName *uint16, lpExtension *uint16, nBuffer |
| 132 | 132 |
return |
| 133 | 133 |
} |
| 134 | 134 |
|
| 135 |
+func NtOpenJobObject(jobHandle *windows.Handle, desiredAccess uint32, objAttributes *ObjectAttributes) (status uint32) {
|
|
| 136 |
+ r0, _, _ := syscall.Syscall(procNtOpenJobObject.Addr(), 3, uintptr(unsafe.Pointer(jobHandle)), uintptr(desiredAccess), uintptr(unsafe.Pointer(objAttributes))) |
|
| 137 |
+ status = uint32(r0) |
|
| 138 |
+ return |
|
| 139 |
+} |
|
| 140 |
+ |
|
| 141 |
+func NtCreateJobObject(jobHandle *windows.Handle, desiredAccess uint32, objAttributes *ObjectAttributes) (status uint32) {
|
|
| 142 |
+ r0, _, _ := syscall.Syscall(procNtCreateJobObject.Addr(), 3, uintptr(unsafe.Pointer(jobHandle)), uintptr(desiredAccess), uintptr(unsafe.Pointer(objAttributes))) |
|
| 143 |
+ status = uint32(r0) |
|
| 144 |
+ return |
|
| 145 |
+} |
|
| 146 |
+ |
|
| 135 | 147 |
func LogonUser(username *uint16, domain *uint16, password *uint16, logonType uint32, logonProvider uint32, token *windows.Token) (err error) {
|
| 136 | 148 |
r1, _, e1 := syscall.Syscall6(procLogonUserW.Addr(), 6, uintptr(unsafe.Pointer(username)), uintptr(unsafe.Pointer(domain)), uintptr(unsafe.Pointer(password)), uintptr(logonType), uintptr(logonProvider), uintptr(unsafe.Pointer(token))) |
| 137 | 149 |
if r1 == 0 {
|
| ... | ... |
@@ -167,6 +242,31 @@ func LocalFree(ptr uintptr) {
|
| 167 | 167 |
return |
| 168 | 168 |
} |
| 169 | 169 |
|
| 170 |
+func QueryWorkingSet(handle windows.Handle, pv uintptr, cb uint32) (err error) {
|
|
| 171 |
+ r1, _, e1 := syscall.Syscall(procQueryWorkingSet.Addr(), 3, uintptr(handle), uintptr(pv), uintptr(cb)) |
|
| 172 |
+ if r1 == 0 {
|
|
| 173 |
+ if e1 != 0 {
|
|
| 174 |
+ err = errnoErr(e1) |
|
| 175 |
+ } else {
|
|
| 176 |
+ err = syscall.EINVAL |
|
| 177 |
+ } |
|
| 178 |
+ } |
|
| 179 |
+ return |
|
| 180 |
+} |
|
| 181 |
+ |
|
| 182 |
+func GetProcessImageFileName(hProcess windows.Handle, imageFileName *uint16, nSize uint32) (size uint32, err error) {
|
|
| 183 |
+ r0, _, e1 := syscall.Syscall(procGetProcessImageFileNameW.Addr(), 3, uintptr(hProcess), uintptr(unsafe.Pointer(imageFileName)), uintptr(nSize)) |
|
| 184 |
+ size = uint32(r0) |
|
| 185 |
+ if size == 0 {
|
|
| 186 |
+ if e1 != 0 {
|
|
| 187 |
+ err = errnoErr(e1) |
|
| 188 |
+ } else {
|
|
| 189 |
+ err = syscall.EINVAL |
|
| 190 |
+ } |
|
| 191 |
+ } |
|
| 192 |
+ return |
|
| 193 |
+} |
|
| 194 |
+ |
|
| 170 | 195 |
func GetActiveProcessorCount(groupNumber uint16) (amount uint32) {
|
| 171 | 196 |
r0, _, _ := syscall.Syscall(procGetActiveProcessorCount.Addr(), 1, uintptr(groupNumber), 0, 0) |
| 172 | 197 |
amount = uint32(r0) |
| ... | ... |
@@ -15,21 +15,6 @@ type OSVersion struct {
|
| 15 | 15 |
Build uint16 |
| 16 | 16 |
} |
| 17 | 17 |
|
| 18 |
-// https://msdn.microsoft.com/en-us/library/windows/desktop/ms724833(v=vs.85).aspx |
|
| 19 |
-type osVersionInfoEx struct {
|
|
| 20 |
- OSVersionInfoSize uint32 |
|
| 21 |
- MajorVersion uint32 |
|
| 22 |
- MinorVersion uint32 |
|
| 23 |
- BuildNumber uint32 |
|
| 24 |
- PlatformID uint32 |
|
| 25 |
- CSDVersion [128]uint16 |
|
| 26 |
- ServicePackMajor uint16 |
|
| 27 |
- ServicePackMinor uint16 |
|
| 28 |
- SuiteMask uint16 |
|
| 29 |
- ProductType byte |
|
| 30 |
- Reserve byte |
|
| 31 |
-} |
|
| 32 |
- |
|
| 33 | 18 |
// Get gets the operating system version on Windows. |
| 34 | 19 |
// The calling application must be manifested to get the correct version information. |
| 35 | 20 |
func Get() OSVersion {
|