summaryrefslogtreecommitdiff
path: root/vendor/github.com/Microsoft/hcsshim/internal/wclayer
diff options
context:
space:
mode:
Diffstat (limited to 'vendor/github.com/Microsoft/hcsshim/internal/wclayer')
-rw-r--r--vendor/github.com/Microsoft/hcsshim/internal/wclayer/expandscratchsize.go115
-rw-r--r--vendor/github.com/Microsoft/hcsshim/internal/wclayer/layerid.go2
-rw-r--r--vendor/github.com/Microsoft/hcsshim/internal/wclayer/layerutils.go2
-rw-r--r--vendor/github.com/Microsoft/hcsshim/internal/wclayer/nametoguid.go2
-rw-r--r--vendor/github.com/Microsoft/hcsshim/internal/wclayer/wclayer.go7
-rw-r--r--vendor/github.com/Microsoft/hcsshim/internal/wclayer/zsyscall_windows.go59
6 files changed, 183 insertions, 4 deletions
diff --git a/vendor/github.com/Microsoft/hcsshim/internal/wclayer/expandscratchsize.go b/vendor/github.com/Microsoft/hcsshim/internal/wclayer/expandscratchsize.go
index 651676fb2..b3b431e35 100644
--- a/vendor/github.com/Microsoft/hcsshim/internal/wclayer/expandscratchsize.go
+++ b/vendor/github.com/Microsoft/hcsshim/internal/wclayer/expandscratchsize.go
@@ -1,7 +1,13 @@
package wclayer
import (
+ "os"
+ "path/filepath"
+ "syscall"
+ "unsafe"
+
"github.com/Microsoft/hcsshim/internal/hcserror"
+ "github.com/Microsoft/hcsshim/osversion"
"github.com/sirupsen/logrus"
)
@@ -26,5 +32,114 @@ func ExpandScratchSize(path string, size uint64) (err error) {
if err != nil {
return hcserror.New(err, title+" - failed", "")
}
+
+ // Manually expand the volume now in order to work around bugs in 19H1 and
+ // prerelease versions of Vb. Remove once this is fixed in Windows.
+ if build := osversion.Get().Build; build >= osversion.V19H1 && build < 19020 {
+ err = expandSandboxVolume(path)
+ if err != nil {
+ return err
+ }
+ }
+ return nil
+}
+
+type virtualStorageType struct {
+ DeviceID uint32
+ VendorID [16]byte
+}
+
+type openVersion2 struct {
+ GetInfoOnly int32 // bool but 4-byte aligned
+ ReadOnly int32 // bool but 4-byte aligned
+ ResiliencyGUID [16]byte // GUID
+}
+
+type openVirtualDiskParameters struct {
+ Version uint32 // Must always be set to 2
+ Version2 openVersion2
+}
+
+func attachVhd(path string) (syscall.Handle, error) {
+ var (
+ defaultType virtualStorageType
+ handle syscall.Handle
+ )
+ parameters := openVirtualDiskParameters{Version: 2}
+ err := openVirtualDisk(
+ &defaultType,
+ path,
+ 0,
+ 0,
+ &parameters,
+ &handle)
+ if err != nil {
+ return 0, &os.PathError{Op: "OpenVirtualDisk", Path: path, Err: err}
+ }
+ err = attachVirtualDisk(handle, 0, 0, 0, 0, 0)
+ if err != nil {
+ syscall.Close(handle)
+ return 0, &os.PathError{Op: "AttachVirtualDisk", Path: path, Err: err}
+ }
+ return handle, nil
+}
+
+func expandSandboxVolume(path string) error {
+ // Mount the sandbox VHD temporarily.
+ vhdPath := filepath.Join(path, "sandbox.vhdx")
+ vhd, err := attachVhd(vhdPath)
+ if err != nil {
+ return &os.PathError{Op: "OpenVirtualDisk", Path: vhdPath, Err: err}
+ }
+ defer syscall.Close(vhd)
+
+ // Open the volume.
+ volumePath, err := GetLayerMountPath(path)
+ if err != nil {
+ return err
+ }
+ if volumePath[len(volumePath)-1] == '\\' {
+ volumePath = volumePath[:len(volumePath)-1]
+ }
+ volume, err := os.OpenFile(volumePath, os.O_RDWR, 0)
+ if err != nil {
+ return err
+ }
+ defer volume.Close()
+
+ // Get the volume's underlying partition size in NTFS clusters.
+ var (
+ partitionSize int64
+ bytes uint32
+ )
+ const _IOCTL_DISK_GET_LENGTH_INFO = 0x0007405C
+ err = syscall.DeviceIoControl(syscall.Handle(volume.Fd()), _IOCTL_DISK_GET_LENGTH_INFO, nil, 0, (*byte)(unsafe.Pointer(&partitionSize)), 8, &bytes, nil)
+ if err != nil {
+ return &os.PathError{Op: "IOCTL_DISK_GET_LENGTH_INFO", Path: volume.Name(), Err: err}
+ }
+ const (
+ clusterSize = 4096
+ sectorSize = 512
+ )
+ targetClusters := partitionSize / clusterSize
+
+ // Get the volume's current size in NTFS clusters.
+ var volumeSize int64
+ err = getDiskFreeSpaceEx(volume.Name()+"\\", nil, &volumeSize, nil)
+ if err != nil {
+ return &os.PathError{Op: "GetDiskFreeSpaceEx", Path: volume.Name(), Err: err}
+ }
+ volumeClusters := volumeSize / clusterSize
+
+ // Only resize the volume if there is space to grow, otherwise this will
+ // fail with invalid parameter. NTFS reserves one cluster.
+ if volumeClusters+1 < targetClusters {
+ targetSectors := targetClusters * (clusterSize / sectorSize)
+ const _FSCTL_EXTEND_VOLUME = 0x000900F0
+ err = syscall.DeviceIoControl(syscall.Handle(volume.Fd()), _FSCTL_EXTEND_VOLUME, (*byte)(unsafe.Pointer(&targetSectors)), 8, nil, 0, &bytes, nil)
+ if err != nil {
+ return &os.PathError{Op: "FSCTL_EXTEND_VOLUME", Path: volume.Name(), Err: err}
+ }
+ }
return nil
}
diff --git a/vendor/github.com/Microsoft/hcsshim/internal/wclayer/layerid.go b/vendor/github.com/Microsoft/hcsshim/internal/wclayer/layerid.go
index 90df3bedc..443596fba 100644
--- a/vendor/github.com/Microsoft/hcsshim/internal/wclayer/layerid.go
+++ b/vendor/github.com/Microsoft/hcsshim/internal/wclayer/layerid.go
@@ -3,7 +3,7 @@ package wclayer
import (
"path/filepath"
- "github.com/Microsoft/hcsshim/internal/guid"
+ "github.com/Microsoft/go-winio/pkg/guid"
)
// LayerID returns the layer ID of a layer on disk.
diff --git a/vendor/github.com/Microsoft/hcsshim/internal/wclayer/layerutils.go b/vendor/github.com/Microsoft/hcsshim/internal/wclayer/layerutils.go
index 6d0ae8a07..06671309d 100644
--- a/vendor/github.com/Microsoft/hcsshim/internal/wclayer/layerutils.go
+++ b/vendor/github.com/Microsoft/hcsshim/internal/wclayer/layerutils.go
@@ -6,7 +6,7 @@ package wclayer
import (
"syscall"
- "github.com/Microsoft/hcsshim/internal/guid"
+ "github.com/Microsoft/go-winio/pkg/guid"
"github.com/sirupsen/logrus"
)
diff --git a/vendor/github.com/Microsoft/hcsshim/internal/wclayer/nametoguid.go b/vendor/github.com/Microsoft/hcsshim/internal/wclayer/nametoguid.go
index 45a63cf65..a259c1b82 100644
--- a/vendor/github.com/Microsoft/hcsshim/internal/wclayer/nametoguid.go
+++ b/vendor/github.com/Microsoft/hcsshim/internal/wclayer/nametoguid.go
@@ -1,7 +1,7 @@
package wclayer
import (
- "github.com/Microsoft/hcsshim/internal/guid"
+ "github.com/Microsoft/go-winio/pkg/guid"
"github.com/Microsoft/hcsshim/internal/hcserror"
"github.com/sirupsen/logrus"
)
diff --git a/vendor/github.com/Microsoft/hcsshim/internal/wclayer/wclayer.go b/vendor/github.com/Microsoft/hcsshim/internal/wclayer/wclayer.go
index 78f2aacd8..dc40bf519 100644
--- a/vendor/github.com/Microsoft/hcsshim/internal/wclayer/wclayer.go
+++ b/vendor/github.com/Microsoft/hcsshim/internal/wclayer/wclayer.go
@@ -1,6 +1,6 @@
package wclayer
-import "github.com/Microsoft/hcsshim/internal/guid"
+import "github.com/Microsoft/go-winio/pkg/guid"
//go:generate go run ../../mksyscall_windows.go -output zsyscall_windows.go wclayer.go
@@ -24,4 +24,9 @@ import "github.com/Microsoft/hcsshim/internal/guid"
//sys grantVmAccess(vmid string, filepath string) (hr error) = vmcompute.GrantVmAccess?
+//sys openVirtualDisk(virtualStorageType *virtualStorageType, path string, virtualDiskAccessMask uint32, flags uint32, parameters *openVirtualDiskParameters, handle *syscall.Handle) (err error) [failretval != 0] = virtdisk.OpenVirtualDisk
+//sys attachVirtualDisk(handle syscall.Handle, sd uintptr, flags uint32, providerFlags uint32, params uintptr, overlapped uintptr) (err error) [failretval != 0] = virtdisk.AttachVirtualDisk
+
+//sys getDiskFreeSpaceEx(directoryName string, freeBytesAvailableToCaller *int64, totalNumberOfBytes *int64, totalNumberOfFreeBytes *int64) (err error) = GetDiskFreeSpaceExW
+
type _guid = guid.GUID
diff --git a/vendor/github.com/Microsoft/hcsshim/internal/wclayer/zsyscall_windows.go b/vendor/github.com/Microsoft/hcsshim/internal/wclayer/zsyscall_windows.go
index d853ab259..67f917f07 100644
--- a/vendor/github.com/Microsoft/hcsshim/internal/wclayer/zsyscall_windows.go
+++ b/vendor/github.com/Microsoft/hcsshim/internal/wclayer/zsyscall_windows.go
@@ -38,6 +38,8 @@ func errnoErr(e syscall.Errno) error {
var (
modvmcompute = windows.NewLazySystemDLL("vmcompute.dll")
+ modvirtdisk = windows.NewLazySystemDLL("virtdisk.dll")
+ modkernel32 = windows.NewLazySystemDLL("kernel32.dll")
procActivateLayer = modvmcompute.NewProc("ActivateLayer")
procCopyLayer = modvmcompute.NewProc("CopyLayer")
@@ -57,6 +59,9 @@ var (
procProcessBaseImage = modvmcompute.NewProc("ProcessBaseImage")
procProcessUtilityImage = modvmcompute.NewProc("ProcessUtilityImage")
procGrantVmAccess = modvmcompute.NewProc("GrantVmAccess")
+ procOpenVirtualDisk = modvirtdisk.NewProc("OpenVirtualDisk")
+ procAttachVirtualDisk = modvirtdisk.NewProc("AttachVirtualDisk")
+ procGetDiskFreeSpaceExW = modkernel32.NewProc("GetDiskFreeSpaceExW")
)
func activateLayer(info *driverInfo, id string) (hr error) {
@@ -508,3 +513,57 @@ func _grantVmAccess(vmid *uint16, filepath *uint16) (hr error) {
}
return
}
+
+func openVirtualDisk(virtualStorageType *virtualStorageType, path string, virtualDiskAccessMask uint32, flags uint32, parameters *openVirtualDiskParameters, handle *syscall.Handle) (err error) {
+ var _p0 *uint16
+ _p0, err = syscall.UTF16PtrFromString(path)
+ if err != nil {
+ return
+ }
+ return _openVirtualDisk(virtualStorageType, _p0, virtualDiskAccessMask, flags, parameters, handle)
+}
+
+func _openVirtualDisk(virtualStorageType *virtualStorageType, path *uint16, virtualDiskAccessMask uint32, flags uint32, parameters *openVirtualDiskParameters, handle *syscall.Handle) (err error) {
+ 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)))
+ if r1 != 0 {
+ if e1 != 0 {
+ err = errnoErr(e1)
+ } else {
+ err = syscall.EINVAL
+ }
+ }
+ return
+}
+
+func attachVirtualDisk(handle syscall.Handle, sd uintptr, flags uint32, providerFlags uint32, params uintptr, overlapped uintptr) (err error) {
+ r1, _, e1 := syscall.Syscall6(procAttachVirtualDisk.Addr(), 6, uintptr(handle), uintptr(sd), uintptr(flags), uintptr(providerFlags), uintptr(params), uintptr(overlapped))
+ if r1 != 0 {
+ if e1 != 0 {
+ err = errnoErr(e1)
+ } else {
+ err = syscall.EINVAL
+ }
+ }
+ return
+}
+
+func getDiskFreeSpaceEx(directoryName string, freeBytesAvailableToCaller *int64, totalNumberOfBytes *int64, totalNumberOfFreeBytes *int64) (err error) {
+ var _p0 *uint16
+ _p0, err = syscall.UTF16PtrFromString(directoryName)
+ if err != nil {
+ return
+ }
+ return _getDiskFreeSpaceEx(_p0, freeBytesAvailableToCaller, totalNumberOfBytes, totalNumberOfFreeBytes)
+}
+
+func _getDiskFreeSpaceEx(directoryName *uint16, freeBytesAvailableToCaller *int64, totalNumberOfBytes *int64, totalNumberOfFreeBytes *int64) (err error) {
+ r1, _, e1 := syscall.Syscall6(procGetDiskFreeSpaceExW.Addr(), 4, uintptr(unsafe.Pointer(directoryName)), uintptr(unsafe.Pointer(freeBytesAvailableToCaller)), uintptr(unsafe.Pointer(totalNumberOfBytes)), uintptr(unsafe.Pointer(totalNumberOfFreeBytes)), 0, 0)
+ if r1 == 0 {
+ if e1 != 0 {
+ err = errnoErr(e1)
+ } else {
+ err = syscall.EINVAL
+ }
+ }
+ return
+}