Windows: Block ReFS file systems
| ... | ... |
@@ -6,6 +6,7 @@ import ( |
| 6 | 6 |
"bufio" |
| 7 | 7 |
"bytes" |
| 8 | 8 |
"encoding/json" |
| 9 |
+ "errors" |
|
| 9 | 10 |
"fmt" |
| 10 | 11 |
"io" |
| 11 | 12 |
"io/ioutil" |
| ... | ... |
@@ -74,6 +75,15 @@ func isTP5OrOlder() bool {
|
| 74 | 74 |
// InitFilter returns a new Windows storage filter driver. |
| 75 | 75 |
func InitFilter(home string, options []string, uidMaps, gidMaps []idtools.IDMap) (graphdriver.Driver, error) {
|
| 76 | 76 |
logrus.Debugf("WindowsGraphDriver InitFilter at %s", home)
|
| 77 |
+ |
|
| 78 |
+ fsType, err := getFileSystemType(string(home[0])) |
|
| 79 |
+ if err != nil {
|
|
| 80 |
+ return nil, err |
|
| 81 |
+ } |
|
| 82 |
+ if strings.ToLower(fsType) == "refs" {
|
|
| 83 |
+ return nil, fmt.Errorf("%s is on an ReFS volume - ReFS volumes are not supported", home)
|
|
| 84 |
+ } |
|
| 85 |
+ |
|
| 77 | 86 |
d := &Driver{
|
| 78 | 87 |
info: hcsshim.DriverInfo{
|
| 79 | 88 |
HomeDir: home, |
| ... | ... |
@@ -85,6 +95,37 @@ func InitFilter(home string, options []string, uidMaps, gidMaps []idtools.IDMap) |
| 85 | 85 |
return d, nil |
| 86 | 86 |
} |
| 87 | 87 |
|
| 88 |
+// win32FromHresult is a helper function to get the win32 error code from an HRESULT |
|
| 89 |
+func win32FromHresult(hr uintptr) uintptr {
|
|
| 90 |
+ if hr&0x1fff0000 == 0x00070000 {
|
|
| 91 |
+ return hr & 0xffff |
|
| 92 |
+ } |
|
| 93 |
+ return hr |
|
| 94 |
+} |
|
| 95 |
+ |
|
| 96 |
+// getFileSystemType obtains the type of a file system through GetVolumeInformation |
|
| 97 |
+// https://msdn.microsoft.com/en-us/library/windows/desktop/aa364993(v=vs.85).aspx |
|
| 98 |
+func getFileSystemType(drive string) (fsType string, hr error) {
|
|
| 99 |
+ var ( |
|
| 100 |
+ modkernel32 = syscall.NewLazyDLL("kernel32.dll")
|
|
| 101 |
+ procGetVolumeInformation = modkernel32.NewProc("GetVolumeInformationW")
|
|
| 102 |
+ buf = make([]uint16, 255) |
|
| 103 |
+ size = syscall.MAX_PATH + 1 |
|
| 104 |
+ ) |
|
| 105 |
+ if len(drive) != 1 {
|
|
| 106 |
+ hr = errors.New("getFileSystemType must be called with a drive letter")
|
|
| 107 |
+ return |
|
| 108 |
+ } |
|
| 109 |
+ drive += `:\` |
|
| 110 |
+ n := uintptr(unsafe.Pointer(nil)) |
|
| 111 |
+ r0, _, _ := syscall.Syscall9(procGetVolumeInformation.Addr(), 8, uintptr(unsafe.Pointer(syscall.StringToUTF16Ptr(drive))), n, n, n, n, n, uintptr(unsafe.Pointer(&buf[0])), uintptr(size), 0) |
|
| 112 |
+ if int32(r0) < 0 {
|
|
| 113 |
+ hr = syscall.Errno(win32FromHresult(r0)) |
|
| 114 |
+ } |
|
| 115 |
+ fsType = syscall.UTF16ToString(buf) |
|
| 116 |
+ return |
|
| 117 |
+} |
|
| 118 |
+ |
|
| 88 | 119 |
// String returns the string representation of a driver. This should match |
| 89 | 120 |
// the name the graph driver has been registered with. |
| 90 | 121 |
func (d *Driver) String() string {
|