storj.io/minio@v0.0.0-20230509071714-0cbc90f649b1/pkg/sys/stats_linux.go (about)

     1  //go:build linux && !arm && !386
     2  // +build linux,!arm,!386
     3  
     4  /*
     5   * MinIO Cloud Storage, (C) 2016,2017 MinIO, Inc.
     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 sys
    21  
    22  import (
    23  	"os"
    24  	"syscall"
    25  
    26  	"storj.io/minio/pkg/cgroup"
    27  )
    28  
    29  // Get the final system memory limit chosen by the user.
    30  // by default without any configuration on a vanilla Linux
    31  // system you would see physical RAM limit. If cgroup
    32  // is configured at some point in time this function
    33  // would return the memory limit chosen for the given pid.
    34  func getMemoryLimit() (sysLimit uint64, err error) {
    35  	if sysLimit, err = getSysinfoMemoryLimit(); err != nil {
    36  		// Physical memory info is not accessible, just exit here.
    37  		return 0, err
    38  	}
    39  
    40  	// Following code is deliberately ignoring the error.
    41  	cGroupLimit, gerr := cgroup.GetMemoryLimit(os.Getpid())
    42  	if gerr != nil {
    43  		// Upon error just return system limit.
    44  		return sysLimit, nil
    45  	}
    46  
    47  	// cgroup limit is lesser than system limit means
    48  	// user wants to limit the memory usage further
    49  	// treat cgroup limit as the system limit.
    50  	if cGroupLimit <= sysLimit {
    51  		sysLimit = cGroupLimit
    52  	}
    53  
    54  	// Final system limit.
    55  	return sysLimit, nil
    56  
    57  }
    58  
    59  // Get physical RAM size of the node.
    60  func getSysinfoMemoryLimit() (limit uint64, err error) {
    61  	var si syscall.Sysinfo_t
    62  	if err = syscall.Sysinfo(&si); err != nil {
    63  		return 0, err
    64  	}
    65  
    66  	// Some fields in syscall.Sysinfo_t have different  integer sizes
    67  	// in different platform architectures. Cast all fields to uint64.
    68  	unit := si.Unit
    69  	totalRAM := si.Totalram
    70  
    71  	// Total RAM is always the multiplicative value
    72  	// of unit size and total ram.
    73  	return uint64(unit) * uint64(totalRAM), nil
    74  }
    75  
    76  // GetStats - return system statistics, currently only
    77  // supported value is TotalRAM.
    78  func GetStats() (stats Stats, err error) {
    79  	var limit uint64
    80  	limit, err = getMemoryLimit()
    81  	if err != nil {
    82  		return Stats{}, err
    83  	}
    84  
    85  	stats.TotalRAM = limit
    86  	return stats, nil
    87  }