diff --git a/pkg/kubelet/volumes.go b/pkg/kubelet/volumes.go index b8e48efd7be..8386e1a6f38 100644 --- a/pkg/kubelet/volumes.go +++ b/pkg/kubelet/volumes.go @@ -154,12 +154,19 @@ func (kl *Kubelet) getPodVolumes(podUID types.UID) ([]*volumeTuple, error) { for _, volumeKindDir := range volumeKindDirs { volumeKind := volumeKindDir.Name() volumeKindPath := path.Join(podVolDir, volumeKind) - volumeNameDirs, err := ioutil.ReadDir(volumeKindPath) + // ioutil.ReadDir exits without returning any healthy dir when encountering the first lstat error + // but skipping dirs means no cleanup for healthy volumes. switching to a no-exit api solves this problem + volumeNameDirs, volumeNameDirsStat, err := util.ReadDirNoExit(volumeKindPath) if err != nil { return []*volumeTuple{}, fmt.Errorf("could not read directory %s: %v", volumeKindPath, err) } - for _, volumeNameDir := range volumeNameDirs { - volumes = append(volumes, &volumeTuple{Kind: volumeKind, Name: volumeNameDir.Name()}) + for i, volumeNameDir := range volumeNameDirs { + if volumeNameDir != nil { + volumes = append(volumes, &volumeTuple{Kind: volumeKind, Name: volumeNameDir.Name()}) + } else { + lerr := volumeNameDirsStat[i] + glog.Errorf("Could not read directory %s: %v", podVolDir, lerr) + } } } return volumes, nil diff --git a/pkg/util/util.go b/pkg/util/util.go index 2f84a9b2d68..7954ffe2466 100644 --- a/pkg/util/util.go +++ b/pkg/util/util.go @@ -519,3 +519,35 @@ func FileExists(filename string) (bool, error) { } return true, nil } + +// borrowed from ioutil.ReadDir +// ReadDir reads the directory named by dirname and returns +// a list of directory entries, minus those with lstat errors +func ReadDirNoExit(dirname string) ([]os.FileInfo, []error, error) { + if dirname == "" { + dirname = "." + } + + f, err := os.Open(dirname) + if err != nil { + return nil, nil, err + } + defer f.Close() + + names, err := f.Readdirnames(-1) + list := make([]os.FileInfo, 0, len(names)) + errs := make([]error, 0, len(names)) + for _, filename := range names { + fip, lerr := os.Lstat(dirname + "/" + filename) + if os.IsNotExist(lerr) { + // File disappeared between readdir + stat. + // Just treat it as if it didn't exist. + continue + } + + list = append(list, fip) + errs = append(errs, lerr) + } + + return list, errs, nil +}