...

Source file src/k8s.io/kubernetes/pkg/volume/emptydir/empty_dir_linux.go

Documentation: k8s.io/kubernetes/pkg/volume/emptydir

     1  //go:build linux
     2  // +build linux
     3  
     4  /*
     5  Copyright 2015 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 emptydir
    21  
    22  import (
    23  	"fmt"
    24  	"strings"
    25  
    26  	"golang.org/x/sys/unix"
    27  	"k8s.io/apimachinery/pkg/api/resource"
    28  	"k8s.io/klog/v2"
    29  	"k8s.io/mount-utils"
    30  
    31  	"k8s.io/api/core/v1"
    32  )
    33  
    34  // Defined by Linux - the type number for tmpfs mounts.
    35  const (
    36  	linuxTmpfsMagic     = 0x01021994
    37  	linuxHugetlbfsMagic = 0x958458f6
    38  )
    39  
    40  // realMountDetector implements mountDetector in terms of syscalls.
    41  type realMountDetector struct {
    42  	mounter mount.Interface
    43  }
    44  
    45  // getPageSize obtains page size from the 'pagesize' mount option of the
    46  // mounted volume
    47  func getPageSize(path string, mounter mount.Interface) (*resource.Quantity, error) {
    48  	// Get mount point data for the path
    49  	mountPoints, err := mounter.List()
    50  	if err != nil {
    51  		return nil, fmt.Errorf("error listing mount points: %v", err)
    52  	}
    53  	// Find mount point for the path
    54  	mountPoint, err := func(mps []mount.MountPoint, mpPath string) (*mount.MountPoint, error) {
    55  		for _, mp := range mps {
    56  			if mp.Path == mpPath {
    57  				return &mp, nil
    58  			}
    59  		}
    60  		return nil, fmt.Errorf("mount point for %s not found", mpPath)
    61  	}(mountPoints, path)
    62  	if err != nil {
    63  		return nil, err
    64  	}
    65  	// Get page size from the 'pagesize' option value
    66  	for _, opt := range mountPoint.Opts {
    67  		opt = strings.TrimSpace(opt)
    68  		prefix := "pagesize="
    69  		if strings.HasPrefix(opt, prefix) {
    70  			// NOTE: Adding suffix 'i' as result should be comparable with a medium size.
    71  			// pagesize mount option is specified without a suffix,
    72  			// e.g. pagesize=2M or pagesize=1024M for x86 CPUs
    73  			trimmedOpt := strings.TrimPrefix(opt, prefix)
    74  			if !strings.HasSuffix(trimmedOpt, "i") {
    75  				trimmedOpt = trimmedOpt + "i"
    76  			}
    77  			pageSize, err := resource.ParseQuantity(trimmedOpt)
    78  			if err != nil {
    79  				return nil, fmt.Errorf("error getting page size from '%s' mount option: %v", opt, err)
    80  			}
    81  			return &pageSize, nil
    82  		}
    83  	}
    84  	return nil, fmt.Errorf("no pagesize option specified for %s mount", mountPoint.Path)
    85  }
    86  
    87  func (m *realMountDetector) GetMountMedium(path string, requestedMedium v1.StorageMedium) (v1.StorageMedium, bool, *resource.Quantity, error) {
    88  	klog.V(5).Infof("Determining mount medium of %v", path)
    89  	notMnt, err := m.mounter.IsLikelyNotMountPoint(path)
    90  	if err != nil {
    91  		return v1.StorageMediumDefault, false, nil, fmt.Errorf("IsLikelyNotMountPoint(%q): %v", path, err)
    92  	}
    93  
    94  	buf := unix.Statfs_t{}
    95  	if err := unix.Statfs(path, &buf); err != nil {
    96  		return v1.StorageMediumDefault, false, nil, fmt.Errorf("statfs(%q): %v", path, err)
    97  	}
    98  
    99  	klog.V(3).Infof("Statfs_t of %v: %+v", path, buf)
   100  
   101  	if buf.Type == linuxTmpfsMagic {
   102  		return v1.StorageMediumMemory, !notMnt, nil, nil
   103  	} else if int64(buf.Type) == linuxHugetlbfsMagic {
   104  		// Skip page size detection if requested medium doesn't have size specified
   105  		if requestedMedium == v1.StorageMediumHugePages {
   106  			return v1.StorageMediumHugePages, !notMnt, nil, nil
   107  		}
   108  		// Get page size for the volume mount
   109  		pageSize, err := getPageSize(path, m.mounter)
   110  		if err != nil {
   111  			return v1.StorageMediumHugePages, !notMnt, nil, err
   112  		}
   113  		return v1.StorageMediumHugePages, !notMnt, pageSize, nil
   114  	}
   115  	return v1.StorageMediumDefault, !notMnt, nil, nil
   116  }
   117  

View as plain text