utils.go 1.5 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162
  1. package hcs
  2. import (
  3. "context"
  4. "io"
  5. "syscall"
  6. "github.com/Microsoft/go-winio"
  7. diskutil "github.com/Microsoft/go-winio/vhd"
  8. "github.com/Microsoft/hcsshim/computestorage"
  9. "github.com/pkg/errors"
  10. "golang.org/x/sys/windows"
  11. )
  12. // makeOpenFiles calls winio.MakeOpenFile for each handle in a slice but closes all the handles
  13. // if there is an error.
  14. func makeOpenFiles(hs []syscall.Handle) (_ []io.ReadWriteCloser, err error) {
  15. fs := make([]io.ReadWriteCloser, len(hs))
  16. for i, h := range hs {
  17. if h != syscall.Handle(0) {
  18. if err == nil {
  19. fs[i], err = winio.MakeOpenFile(h)
  20. }
  21. if err != nil {
  22. syscall.Close(h)
  23. }
  24. }
  25. }
  26. if err != nil {
  27. for _, f := range fs {
  28. if f != nil {
  29. f.Close()
  30. }
  31. }
  32. return nil, err
  33. }
  34. return fs, nil
  35. }
  36. // CreateNTFSVHD creates a VHD formatted with NTFS of size `sizeGB` at the given `vhdPath`.
  37. func CreateNTFSVHD(ctx context.Context, vhdPath string, sizeGB uint32) (err error) {
  38. if err := diskutil.CreateVhdx(vhdPath, sizeGB, 1); err != nil {
  39. return errors.Wrap(err, "failed to create VHD")
  40. }
  41. vhd, err := diskutil.OpenVirtualDisk(vhdPath, diskutil.VirtualDiskAccessNone, diskutil.OpenVirtualDiskFlagNone)
  42. if err != nil {
  43. return errors.Wrap(err, "failed to open VHD")
  44. }
  45. defer func() {
  46. err2 := windows.CloseHandle(windows.Handle(vhd))
  47. if err == nil {
  48. err = errors.Wrap(err2, "failed to close VHD")
  49. }
  50. }()
  51. if err := computestorage.FormatWritableLayerVhd(ctx, windows.Handle(vhd)); err != nil {
  52. return errors.Wrap(err, "failed to format VHD")
  53. }
  54. return nil
  55. }