Skip to content

Commit 43b6ddf

Browse files
authored
Merge pull request kubernetes#75087 from andyzhangx/unmount-issue-windows
fix smb unmount issue on Windows
2 parents 243e740 + 720a5e2 commit 43b6ddf

File tree

5 files changed

+121
-27
lines changed

5 files changed

+121
-27
lines changed

pkg/util/mount/BUILD

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,9 @@ go_library(
99
"exec_mount_unsupported.go",
1010
"fake.go",
1111
"mount.go",
12-
"mount_helper.go",
12+
"mount_helper_common.go",
13+
"mount_helper_unix.go",
14+
"mount_helper_windows.go",
1315
"mount_linux.go",
1416
"mount_unsupported.go",
1517
"mount_windows.go",

pkg/util/mount/mount_helper.go renamed to pkg/util/mount/mount_helper_common.go

Lines changed: 0 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,6 @@ package mount
1919
import (
2020
"fmt"
2121
"os"
22-
"syscall"
2322

2423
"k8s.io/klog"
2524
)
@@ -102,23 +101,3 @@ func PathExists(path string) (bool, error) {
102101
return false, err
103102
}
104103
}
105-
106-
// IsCorruptedMnt return true if err is about corrupted mount point
107-
func IsCorruptedMnt(err error) bool {
108-
if err == nil {
109-
return false
110-
}
111-
var underlyingError error
112-
switch pe := err.(type) {
113-
case nil:
114-
return false
115-
case *os.PathError:
116-
underlyingError = pe.Err
117-
case *os.LinkError:
118-
underlyingError = pe.Err
119-
case *os.SyscallError:
120-
underlyingError = pe.Err
121-
}
122-
123-
return underlyingError == syscall.ENOTCONN || underlyingError == syscall.ESTALE || underlyingError == syscall.EIO || underlyingError == syscall.EACCES
124-
}
Lines changed: 44 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,44 @@
1+
// +build !windows
2+
3+
/*
4+
Copyright 2019 The Kubernetes Authors.
5+
6+
Licensed under the Apache License, Version 2.0 (the "License");
7+
you may not use this file except in compliance with the License.
8+
You may obtain a copy of the License at
9+
10+
http://www.apache.org/licenses/LICENSE-2.0
11+
12+
Unless required by applicable law or agreed to in writing, software
13+
distributed under the License is distributed on an "AS IS" BASIS,
14+
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15+
See the License for the specific language governing permissions and
16+
limitations under the License.
17+
*/
18+
19+
package mount
20+
21+
import (
22+
"os"
23+
"syscall"
24+
)
25+
26+
// IsCorruptedMnt return true if err is about corrupted mount point
27+
func IsCorruptedMnt(err error) bool {
28+
if err == nil {
29+
return false
30+
}
31+
var underlyingError error
32+
switch pe := err.(type) {
33+
case nil:
34+
return false
35+
case *os.PathError:
36+
underlyingError = pe.Err
37+
case *os.LinkError:
38+
underlyingError = pe.Err
39+
case *os.SyscallError:
40+
underlyingError = pe.Err
41+
}
42+
43+
return underlyingError == syscall.ENOTCONN || underlyingError == syscall.ESTALE || underlyingError == syscall.EIO || underlyingError == syscall.EACCES
44+
}
Lines changed: 68 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,68 @@
1+
// +build windows
2+
3+
/*
4+
Copyright 2019 The Kubernetes Authors.
5+
6+
Licensed under the Apache License, Version 2.0 (the "License");
7+
you may not use this file except in compliance with the License.
8+
You may obtain a copy of the License at
9+
10+
http://www.apache.org/licenses/LICENSE-2.0
11+
12+
Unless required by applicable law or agreed to in writing, software
13+
distributed under the License is distributed on an "AS IS" BASIS,
14+
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15+
See the License for the specific language governing permissions and
16+
limitations under the License.
17+
*/
18+
19+
package mount
20+
21+
import (
22+
"os"
23+
"syscall"
24+
25+
"k8s.io/klog"
26+
)
27+
28+
// following failure codes are from https://docs.microsoft.com/en-us/windows/desktop/debug/system-error-codes--1300-1699-
29+
// ERROR_BAD_NETPATH = 53
30+
// ERROR_NETWORK_BUSY = 54
31+
// ERROR_UNEXP_NET_ERR = 59
32+
// ERROR_NETNAME_DELETED = 64
33+
// ERROR_NETWORK_ACCESS_DENIED = 65
34+
// ERROR_BAD_DEV_TYPE = 66
35+
// ERROR_BAD_NET_NAME = 67
36+
// ERROR_SESSION_CREDENTIAL_CONFLICT = 1219
37+
// ERROR_LOGON_FAILURE = 1326
38+
var errorNoList = [...]int{53, 54, 59, 64, 65, 66, 67, 1219, 1326}
39+
40+
// IsCorruptedMnt return true if err is about corrupted mount point
41+
func IsCorruptedMnt(err error) bool {
42+
if err == nil {
43+
return false
44+
}
45+
46+
var underlyingError error
47+
switch pe := err.(type) {
48+
case nil:
49+
return false
50+
case *os.PathError:
51+
underlyingError = pe.Err
52+
case *os.LinkError:
53+
underlyingError = pe.Err
54+
case *os.SyscallError:
55+
underlyingError = pe.Err
56+
}
57+
58+
if ee, ok := underlyingError.(syscall.Errno); ok {
59+
for _, errno := range errorNoList {
60+
if int(ee) == errno {
61+
klog.Warningf("IsCorruptedMnt failed with error: %v, error code: %v", err, errno)
62+
return true
63+
}
64+
}
65+
}
66+
67+
return false
68+
}

pkg/util/mount/mount_windows.go

Lines changed: 6 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -378,14 +378,15 @@ func getAllParentLinks(path string) ([]string, error) {
378378

379379
// GetMountRefs : empty implementation here since there is no place to query all mount points on Windows
380380
func (mounter *Mounter) GetMountRefs(pathname string) ([]string, error) {
381-
pathExists, pathErr := PathExists(normalizeWindowsPath(pathname))
382-
// TODO(#75012): Need a Windows specific IsCorruptedMnt function that checks against whatever errno's
383-
// Windows emits when we try to Stat a corrupted mount
384-
// https://golang.org/pkg/syscall/?GOOS=windows&GOARCH=amd64#Errno
381+
windowsPath := normalizeWindowsPath(pathname)
382+
pathExists, pathErr := PathExists(windowsPath)
385383
if !pathExists {
386384
return []string{}, nil
385+
} else if IsCorruptedMnt(pathErr) {
386+
klog.Warningf("GetMountRefs found corrupted mount at %s, treating as unmounted path", windowsPath)
387+
return []string{}, nil
387388
} else if pathErr != nil {
388-
return nil, fmt.Errorf("error checking path %s: %v", normalizeWindowsPath(pathname), pathErr)
389+
return nil, fmt.Errorf("error checking path %s: %v", windowsPath, pathErr)
389390
}
390391
return []string{pathname}, nil
391392
}

0 commit comments

Comments
 (0)