From 1636b2b452e450cc8bfdeb90e5fd820faa7d9095 Mon Sep 17 00:00:00 2001 From: Jing Xu Date: Mon, 7 Oct 2019 14:23:09 -0700 Subject: [PATCH] Flush data cache during unmount device for GCE-PD in Windows This PR fixes the issue mentioned in #83590 for GCE-PD. It uses WriteVolumeCache API to writes the file system cache to disk during UnmountDevice in Windows. Linux does not need to explicitly flush cache because unmount will automatically sync the disk which also flush the cache. Change-Id: Ife2745c92b8c0446e79a52e9f9ec7851d2f6b90d --- pkg/volume/gcepd/attacher.go | 8 ++++++++ pkg/volume/util/util.go | 20 ++++++++++++++++++-- 2 files changed, 26 insertions(+), 2 deletions(-) diff --git a/pkg/volume/gcepd/attacher.go b/pkg/volume/gcepd/attacher.go index 9d67f67f584..9a481afce06 100644 --- a/pkg/volume/gcepd/attacher.go +++ b/pkg/volume/gcepd/attacher.go @@ -384,6 +384,14 @@ func (detacher *gcePersistentDiskDetacher) Detach(volumeName string, nodeName ty } func (detacher *gcePersistentDiskDetacher) UnmountDevice(deviceMountPath string) error { + if runtime.GOOS == "windows" { + // Flush data cache for windows because it does not do so automatically during unmount device + exec := detacher.host.GetExec(gcePersistentDiskPluginName) + err := volumeutil.WriteVolumeCache(deviceMountPath, exec) + if err != nil { + return err + } + } return mount.CleanupMountPoint(deviceMountPath, detacher.host.GetMounter(gcePersistentDiskPluginName), false) } diff --git a/pkg/volume/util/util.go b/pkg/volume/util/util.go index 4eee6e9c526..72352feb1ec 100644 --- a/pkg/volume/util/util.go +++ b/pkg/volume/util/util.go @@ -22,6 +22,7 @@ import ( "os" "path/filepath" "reflect" + "runtime" "strings" v1 "k8s.io/api/core/v1" @@ -29,7 +30,7 @@ import ( "k8s.io/apimachinery/pkg/api/resource" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" "k8s.io/apimachinery/pkg/labels" - "k8s.io/apimachinery/pkg/runtime" + apiruntime "k8s.io/apimachinery/pkg/runtime" utypes "k8s.io/apimachinery/pkg/types" "k8s.io/apimachinery/pkg/util/sets" utilfeature "k8s.io/apiserver/pkg/util/feature" @@ -196,7 +197,7 @@ func LoadPodFromFile(filePath string) (*v1.Pod, error) { pod := &v1.Pod{} codec := legacyscheme.Codecs.UniversalDecoder() - if err := runtime.DecodeInto(codec, podDef, pod); err != nil { + if err := apiruntime.DecodeInto(codec, podDef, pod); err != nil { return nil, fmt.Errorf("failed decoding file: %v", err) } return pod, nil @@ -582,3 +583,18 @@ func HasMountRefs(mountPath string, mountRefs []string) bool { } return false } + +//WriteVolumeCache flush disk data given the spcified mount path +func WriteVolumeCache(deviceMountPath string, exec mount.Exec) error { + // If runtime os is windows, execute Write-VolumeCache powershell command on the disk + if runtime.GOOS == "windows" { + cmd := fmt.Sprintf("Get-Volume -FilePath %s | Write-Volumecache", deviceMountPath) + output, err := exec.Run("powershell", "/c", cmd) + klog.Infof("command (%q) execeuted: %v, output: %q", cmd, err, string(output)) + if err != nil { + return fmt.Errorf("command (%q) failed: %v, output: %q", cmd, err, string(output)) + } + } + // For linux runtime, it skips because unmount will automatically flush disk data + return nil +}