...

Source file src/k8s.io/kubernetes/pkg/volume/util/fs/fs_windows.go

Documentation: k8s.io/kubernetes/pkg/volume/util/fs

     1  //go:build windows
     2  // +build windows
     3  
     4  /*
     5  Copyright 2014 The Kubernetes Authors.
     6  
     7  Licensed under the Apache License, Version 2.0 (the "License");
     8  you may not use this file except in compliance with the License.
     9  You may obtain a copy of the License at
    10  
    11      http://www.apache.org/licenses/LICENSE-2.0
    12  
    13  Unless required by applicable law or agreed to in writing, software
    14  distributed under the License is distributed on an "AS IS" BASIS,
    15  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    16  See the License for the specific language governing permissions and
    17  limitations under the License.
    18  */
    19  
    20  package fs
    21  
    22  import (
    23  	"os"
    24  	"path/filepath"
    25  	"syscall"
    26  	"unsafe"
    27  
    28  	"golang.org/x/sys/windows"
    29  )
    30  
    31  var (
    32  	modkernel32            = windows.NewLazySystemDLL("kernel32.dll")
    33  	procGetDiskFreeSpaceEx = modkernel32.NewProc("GetDiskFreeSpaceExW")
    34  )
    35  
    36  type UsageInfo struct {
    37  	Bytes  int64
    38  	Inodes int64
    39  }
    40  
    41  // Info returns (available bytes, byte capacity, byte usage, total inodes, inodes free, inode usage, error)
    42  // for the filesystem that path resides upon.
    43  func Info(path string) (int64, int64, int64, int64, int64, int64, error) {
    44  	var freeBytesAvailable, totalNumberOfBytes, totalNumberOfFreeBytes int64
    45  	var err error
    46  
    47  	// The equivalent linux call supports calls against files but the syscall for windows
    48  	// fails for files with error code: The directory name is invalid. (#99173)
    49  	// https://docs.microsoft.com/en-us/windows/win32/debug/system-error-codes--0-499-
    50  	// By always ensuring the directory path we meet all uses cases of this function
    51  	path = filepath.Dir(path)
    52  	ret, _, err := syscall.Syscall6(
    53  		procGetDiskFreeSpaceEx.Addr(),
    54  		4,
    55  		uintptr(unsafe.Pointer(syscall.StringToUTF16Ptr(path))),
    56  		uintptr(unsafe.Pointer(&freeBytesAvailable)),
    57  		uintptr(unsafe.Pointer(&totalNumberOfBytes)),
    58  		uintptr(unsafe.Pointer(&totalNumberOfFreeBytes)),
    59  		0,
    60  		0,
    61  	)
    62  	if ret == 0 {
    63  		return 0, 0, 0, 0, 0, 0, err
    64  	}
    65  
    66  	return freeBytesAvailable, totalNumberOfBytes, totalNumberOfBytes - freeBytesAvailable, 0, 0, 0, nil
    67  }
    68  
    69  // DiskUsage gets disk usage of specified path.
    70  func DiskUsage(path string) (UsageInfo, error) {
    71  	var usage UsageInfo
    72  	info, err := os.Lstat(path)
    73  	if err != nil {
    74  		return usage, err
    75  	}
    76  
    77  	usage.Bytes, err = diskUsage(path, info)
    78  	return usage, err
    79  }
    80  
    81  func diskUsage(currPath string, info os.FileInfo) (int64, error) {
    82  	var size int64
    83  
    84  	if info.Mode()&os.ModeSymlink != 0 {
    85  		return size, nil
    86  	}
    87  
    88  	size += info.Size()
    89  
    90  	if !info.IsDir() {
    91  		return size, nil
    92  	}
    93  
    94  	dir, err := os.Open(currPath)
    95  	if err != nil {
    96  		return size, err
    97  	}
    98  	defer dir.Close()
    99  
   100  	files, err := dir.Readdir(-1)
   101  	if err != nil {
   102  		return size, err
   103  	}
   104  
   105  	for _, file := range files {
   106  		if file.IsDir() {
   107  			s, err := diskUsage(filepath.Join(currPath, file.Name()), file)
   108  			if err != nil {
   109  				return size, err
   110  			}
   111  			size += s
   112  		} else {
   113  			size += file.Size()
   114  		}
   115  	}
   116  	return size, nil
   117  }
   118  

View as plain text