Skip to content

Commit 5ae2129

Browse files
authored
Merge pull request #1937 from k8s-infra-cherrypick-robot/cherry-pick-1934-to-release-1.29
[release-1.29] fix: refine GetRemoteServerFromTarget on Windows with cache optimization
2 parents 843511c + 5e49225 commit 5ae2129

File tree

4 files changed

+46
-11
lines changed

4 files changed

+46
-11
lines changed

pkg/mounter/safe_mounter_host_process_windows.go

+11-5
Original file line numberDiff line numberDiff line change
@@ -31,16 +31,22 @@ import (
3131

3232
"sigs.k8s.io/azurefile-csi-driver/pkg/os/filesystem"
3333
"sigs.k8s.io/azurefile-csi-driver/pkg/os/smb"
34+
35+
azcache "sigs.k8s.io/cloud-provider-azure/pkg/cache"
3436
)
3537

3638
var driverGlobalMountPath = "C:\\var\\lib\\kubelet\\plugins\\kubernetes.io\\csi\\file.csi.azure.com"
3739

3840
var _ CSIProxyMounter = &winMounter{}
3941

40-
type winMounter struct{}
42+
type winMounter struct {
43+
volStatsCache azcache.Resource
44+
}
4145

42-
func NewWinMounter() *winMounter {
43-
return &winMounter{}
46+
func NewWinMounter(cache azcache.Resource) *winMounter {
47+
return &winMounter{
48+
volStatsCache: cache,
49+
}
4450
}
4551

4652
func (mounter *winMounter) SMBMount(source, target, fsType string, mountOptions, sensitiveMountOptions []string) error {
@@ -131,10 +137,10 @@ func (mounter *winMounter) Rmdir(path string) error {
131137
// Unmount - Removes the directory - equivalent to unmount on Linux.
132138
func (mounter *winMounter) Unmount(target string) error {
133139
target = normalizeWindowsPath(target)
134-
remoteServer, err := smb.GetRemoteServerFromTarget(target)
140+
remoteServer, err := smb.GetRemoteServerFromTarget(target, mounter.volStatsCache)
135141
if err == nil {
136142
klog.V(2).Infof("remote server path: %s, local path: %s", remoteServer, target)
137-
if hasDupSMBMount, err := smb.CheckForDuplicateSMBMounts(driverGlobalMountPath, target, remoteServer); err == nil {
143+
if hasDupSMBMount, err := smb.CheckForDuplicateSMBMounts(driverGlobalMountPath, target, remoteServer, mounter.volStatsCache); err == nil {
138144
if !hasDupSMBMount {
139145
remoteServer = strings.Replace(remoteServer, "UNC\\", "\\\\", 1)
140146
if err := smb.RemoveSmbGlobalMapping(remoteServer); err != nil {

pkg/mounter/safe_mounter_windows.go

+11-1
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,7 @@ import (
2525
"os"
2626
filepath "path/filepath"
2727
"strings"
28+
"time"
2829

2930
fs "github.com/kubernetes-csi/csi-proxy/client/api/filesystem/v1"
3031
fsclient "github.com/kubernetes-csi/csi-proxy/client/groups/filesystem/v1"
@@ -35,6 +36,8 @@ import (
3536
"k8s.io/klog/v2"
3637
mount "k8s.io/mount-utils"
3738
utilexec "k8s.io/utils/exec"
39+
40+
azcache "sigs.k8s.io/cloud-provider-azure/pkg/cache"
3841
)
3942

4043
// CSIProxyMounter extends the mount.Interface interface with CSI Proxy methods.
@@ -293,9 +296,16 @@ func NewCSIProxyMounter() (*csiProxyMounter, error) {
293296

294297
func NewSafeMounter(enableWindowsHostProcess bool) (*mount.SafeFormatAndMount, error) {
295298
if enableWindowsHostProcess {
299+
// initialize the cache for volume stats
300+
getter := func(key string) (interface{}, error) { return nil, nil }
301+
volStatsCache, err := azcache.NewTimedCache(10*time.Minute, getter, false)
302+
if err != nil {
303+
return nil, err
304+
}
305+
296306
klog.V(2).Infof("using windows host process mounter")
297307
return &mount.SafeFormatAndMount{
298-
Interface: NewWinMounter(),
308+
Interface: NewWinMounter(volStatsCache),
299309
Exec: utilexec.New(),
300310
}, nil
301311
}

pkg/os/smb/smb.go

+17-4
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,7 @@ import (
2424

2525
"k8s.io/klog/v2"
2626
"sigs.k8s.io/azurefile-csi-driver/pkg/util"
27+
azcache "sigs.k8s.io/cloud-provider-azure/pkg/cache"
2728
)
2829

2930
func IsSmbMapped(remotePath string) (bool, error) {
@@ -67,17 +68,29 @@ func RemoveSmbGlobalMapping(remotePath string) error {
6768
}
6869

6970
// GetRemoteServerFromTarget- gets the remote server path given a mount point, the function is recursive until it find the remote server or errors out
70-
func GetRemoteServerFromTarget(mount string) (string, error) {
71+
func GetRemoteServerFromTarget(mount string, volStatsCache azcache.Resource) (string, error) {
72+
cache, err := volStatsCache.Get(mount, azcache.CacheReadTypeDefault)
73+
if err != nil {
74+
return "", err
75+
}
76+
if cache != nil {
77+
remoteServer := cache.(string)
78+
klog.V(6).Infof("GetRemoteServerFromTarget(%s) cache hit: %s", mount, remoteServer)
79+
return remoteServer, nil
80+
}
7181
cmd := "(Get-Item -Path $Env:mount).Target"
7282
out, err := util.RunPowershellCmd(cmd, fmt.Sprintf("mount=%s", mount))
7383
if err != nil || len(out) == 0 {
7484
return "", fmt.Errorf("error getting volume from mount. cmd: %s, output: %s, error: %v", cmd, string(out), err)
7585
}
76-
return strings.TrimSpace(string(out)), nil
86+
remoteServer := strings.TrimSpace(string(out))
87+
// cache the remote server path
88+
volStatsCache.Set(mount, remoteServer)
89+
return remoteServer, nil
7790
}
7891

7992
// CheckForDuplicateSMBMounts checks if there is any other SMB mount exists on the same remote server
80-
func CheckForDuplicateSMBMounts(dir, mount, remoteServer string) (bool, error) {
93+
func CheckForDuplicateSMBMounts(dir, mount, remoteServer string, volStatsCache azcache.Resource) (bool, error) {
8194
files, err := os.ReadDir(dir)
8295
if err != nil {
8396
return false, err
@@ -93,7 +106,7 @@ func CheckForDuplicateSMBMounts(dir, mount, remoteServer string) (bool, error) {
93106
fileInfo, err := os.Lstat(globalMountPath)
94107
// check if the file is a symlink, if yes, check if it is pointing to the same remote server
95108
if err == nil && fileInfo.Mode()&os.ModeSymlink != 0 {
96-
remoteServerPath, err := GetRemoteServerFromTarget(globalMountPath)
109+
remoteServerPath, err := GetRemoteServerFromTarget(globalMountPath, volStatsCache)
97110
klog.V(2).Infof("checking remote server path %s on local path %s", remoteServerPath, globalMountPath)
98111
if err == nil {
99112
if remoteServerPath == remoteServer {

pkg/os/smb/smb_test.go

+7-1
Original file line numberDiff line numberDiff line change
@@ -22,9 +22,15 @@ package smb
2222
import (
2323
"fmt"
2424
"testing"
25+
"time"
26+
27+
azcache "sigs.k8s.io/cloud-provider-azure/pkg/cache"
2528
)
2629

2730
func TestCheckForDuplicateSMBMounts(t *testing.T) {
31+
getter := func(key string) (interface{}, error) { return nil, nil }
32+
volStatsCache, _ := azcache.NewTimedCache(10*time.Minute, getter, false)
33+
2834
tests := []struct {
2935
name string
3036
dir string
@@ -42,7 +48,7 @@ func TestCheckForDuplicateSMBMounts(t *testing.T) {
4248
}
4349

4450
for _, test := range tests {
45-
result, err := CheckForDuplicateSMBMounts(test.dir, test.mount, test.remoteServer)
51+
result, err := CheckForDuplicateSMBMounts(test.dir, test.mount, test.remoteServer, volStatsCache)
4652
if result != test.expectedResult {
4753
t.Errorf("Expected %v, got %v", test.expectedResult, result)
4854
}

0 commit comments

Comments
 (0)