diff --git a/computestorage/format.go b/computestorage/format.go index 4a5735e989..2140e5c9fc 100644 --- a/computestorage/format.go +++ b/computestorage/format.go @@ -4,74 +4,29 @@ package computestorage import ( "context" - "os" - "syscall" - "github.com/Microsoft/go-winio/vhd" "github.com/Microsoft/hcsshim/internal/oc" - "github.com/Microsoft/hcsshim/osversion" "github.com/pkg/errors" "golang.org/x/sys/windows" ) -func openDisk(path string) (windows.Handle, error) { - u16, err := windows.UTF16PtrFromString(path) - if err != nil { - return 0, err - } - h, err := windows.CreateFile( - u16, - windows.GENERIC_READ|windows.GENERIC_WRITE, - windows.FILE_SHARE_READ|windows.FILE_SHARE_WRITE, - nil, - windows.OPEN_EXISTING, - windows.FILE_ATTRIBUTE_NORMAL|windows.FILE_FLAG_NO_BUFFERING, - 0, - ) - if err != nil { - return 0, &os.PathError{ - Op: "CreateFile", - Path: path, - Err: err, - } - } - return h, nil -} - // FormatWritableLayerVhd formats a virtual disk for use as a writable container layer. // // If the VHD is not mounted it will be temporarily mounted. +// +// NOTE: This API had a breaking change in the operating system after Windows Server 2019. +// On ws2019 the API expects to get passed a file handle from CreateFile for the vhd that +// the caller wants to format. On > ws2019, its expected that the caller passes a vhd handle +// that can be obtained from the virtdisk APIs. func FormatWritableLayerVhd(ctx context.Context, vhdHandle windows.Handle) (err error) { title := "hcsshim::FormatWritableLayerVhd" ctx, span := oc.StartSpan(ctx, title) //nolint:ineffassign,staticcheck defer span.End() defer func() { oc.SetSpanStatus(span, err) }() - h := vhdHandle - // On RS5 HcsFormatWritableLayerVhd expects to receive a disk handle instead of a vhd handle. - if osversion.Build() < osversion.V19H1 { - if err := vhd.AttachVirtualDisk(syscall.Handle(vhdHandle), vhd.AttachVirtualDiskFlagNone, &vhd.AttachVirtualDiskParameters{Version: 1}); err != nil { - return err - } - defer func() { - if detachErr := vhd.DetachVirtualDisk(syscall.Handle(vhdHandle)); err == nil && detachErr != nil { - err = detachErr - } - }() - diskPath, err := vhd.GetVirtualDiskPhysicalPath(syscall.Handle(vhdHandle)) - if err != nil { - return err - } - diskHandle, err := openDisk(diskPath) - if err != nil { - return err - } - defer windows.CloseHandle(diskHandle) // nolint: errcheck - h = diskHandle - } - err = hcsFormatWritableLayerVhd(h) + err = hcsFormatWritableLayerVhd(vhdHandle) if err != nil { return errors.Wrap(err, "failed to format writable layer vhd") } - return + return nil } diff --git a/computestorage/setup.go b/computestorage/setup.go index faec837ca1..1c685aed0a 100644 --- a/computestorage/setup.go +++ b/computestorage/setup.go @@ -50,6 +50,10 @@ func SetupBaseOSLayer(ctx context.Context, layerPath string, vhdHandle windows.H // `volumePath` is the path to the volume to be used for setup. // // `options` are the options applied while processing the layer. +// +// NOTE: This API is only available on builds of Windows greater than 19645. Inside we +// check if the hosts build has the API available by using 'GetVersion' which requires +// the calling application to be manifested. https://docs.microsoft.com/en-us/windows/win32/sbscs/manifests func SetupBaseOSVolume(ctx context.Context, layerPath, volumePath string, options OsLayerOptions) (err error) { if osversion.Build() < 19645 { return errors.New("SetupBaseOSVolume is not present on builds older than 19645")