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 }