github.com/hellobchain/third_party@v0.0.0-20230331131523-deb0478a2e52/prometheus/procfs/proc_limits.go (about)

     1  // Copyright 2018 The Prometheus Authors
     2  // Licensed under the Apache License, Version 2.0 (the "License");
     3  // you may not use this file except in compliance with the License.
     4  // You may obtain a copy of the License at
     5  //
     6  // http://www.apache.org/licenses/LICENSE-2.0
     7  //
     8  // Unless required by applicable law or agreed to in writing, software
     9  // distributed under the License is distributed on an "AS IS" BASIS,
    10  // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    11  // See the License for the specific language governing permissions and
    12  // limitations under the License.
    13  
    14  package procfs
    15  
    16  import (
    17  	"bufio"
    18  	"fmt"
    19  	"os"
    20  	"regexp"
    21  	"strconv"
    22  )
    23  
    24  // ProcLimits represents the soft limits for each of the process's resource
    25  // limits. For more information see getrlimit(2):
    26  // http://man7.org/linux/man-pages/man2/getrlimit.2.html.
    27  type ProcLimits struct {
    28  	// CPU time limit in seconds.
    29  	CPUTime int64
    30  	// Maximum size of files that the process may create.
    31  	FileSize int64
    32  	// Maximum size of the process's data segment (initialized data,
    33  	// uninitialized data, and heap).
    34  	DataSize int64
    35  	// Maximum size of the process stack in bytes.
    36  	StackSize int64
    37  	// Maximum size of a core file.
    38  	CoreFileSize int64
    39  	// Limit of the process's resident set in pages.
    40  	ResidentSet int64
    41  	// Maximum number of processes that can be created for the real user ID of
    42  	// the calling process.
    43  	Processes int64
    44  	// Value one greater than the maximum file descriptor number that can be
    45  	// opened by this process.
    46  	OpenFiles int64
    47  	// Maximum number of bytes of memory that may be locked into RAM.
    48  	LockedMemory int64
    49  	// Maximum size of the process's virtual memory address space in bytes.
    50  	AddressSpace int64
    51  	// Limit on the combined number of flock(2) locks and fcntl(2) leases that
    52  	// this process may establish.
    53  	FileLocks int64
    54  	// Limit of signals that may be queued for the real user ID of the calling
    55  	// process.
    56  	PendingSignals int64
    57  	// Limit on the number of bytes that can be allocated for POSIX message
    58  	// queues for the real user ID of the calling process.
    59  	MsqqueueSize int64
    60  	// Limit of the nice priority set using setpriority(2) or nice(2).
    61  	NicePriority int64
    62  	// Limit of the real-time priority set using sched_setscheduler(2) or
    63  	// sched_setparam(2).
    64  	RealtimePriority int64
    65  	// Limit (in microseconds) on the amount of CPU time that a process
    66  	// scheduled under a real-time scheduling policy may consume without making
    67  	// a blocking system call.
    68  	RealtimeTimeout int64
    69  }
    70  
    71  const (
    72  	limitsFields    = 3
    73  	limitsUnlimited = "unlimited"
    74  )
    75  
    76  var (
    77  	limitsDelimiter = regexp.MustCompile("  +")
    78  )
    79  
    80  // NewLimits returns the current soft limits of the process.
    81  func (p Proc) NewLimits() (ProcLimits, error) {
    82  	f, err := os.Open(p.path("limits"))
    83  	if err != nil {
    84  		return ProcLimits{}, err
    85  	}
    86  	defer f.Close()
    87  
    88  	var (
    89  		l = ProcLimits{}
    90  		s = bufio.NewScanner(f)
    91  	)
    92  	for s.Scan() {
    93  		fields := limitsDelimiter.Split(s.Text(), limitsFields)
    94  		if len(fields) != limitsFields {
    95  			return ProcLimits{}, fmt.Errorf(
    96  				"couldn't parse %s line %s", f.Name(), s.Text())
    97  		}
    98  
    99  		switch fields[0] {
   100  		case "Max cpu time":
   101  			l.CPUTime, err = parseInt(fields[1])
   102  		case "Max file size":
   103  			l.FileSize, err = parseInt(fields[1])
   104  		case "Max data size":
   105  			l.DataSize, err = parseInt(fields[1])
   106  		case "Max stack size":
   107  			l.StackSize, err = parseInt(fields[1])
   108  		case "Max core file size":
   109  			l.CoreFileSize, err = parseInt(fields[1])
   110  		case "Max resident set":
   111  			l.ResidentSet, err = parseInt(fields[1])
   112  		case "Max processes":
   113  			l.Processes, err = parseInt(fields[1])
   114  		case "Max open files":
   115  			l.OpenFiles, err = parseInt(fields[1])
   116  		case "Max locked memory":
   117  			l.LockedMemory, err = parseInt(fields[1])
   118  		case "Max address space":
   119  			l.AddressSpace, err = parseInt(fields[1])
   120  		case "Max file locks":
   121  			l.FileLocks, err = parseInt(fields[1])
   122  		case "Max pending signals":
   123  			l.PendingSignals, err = parseInt(fields[1])
   124  		case "Max msgqueue size":
   125  			l.MsqqueueSize, err = parseInt(fields[1])
   126  		case "Max nice priority":
   127  			l.NicePriority, err = parseInt(fields[1])
   128  		case "Max realtime priority":
   129  			l.RealtimePriority, err = parseInt(fields[1])
   130  		case "Max realtime timeout":
   131  			l.RealtimeTimeout, err = parseInt(fields[1])
   132  		}
   133  		if err != nil {
   134  			return ProcLimits{}, err
   135  		}
   136  	}
   137  
   138  	return l, s.Err()
   139  }
   140  
   141  func parseInt(s string) (int64, error) {
   142  	if s == limitsUnlimited {
   143  		return -1, nil
   144  	}
   145  	i, err := strconv.ParseInt(s, 10, 64)
   146  	if err != nil {
   147  		return 0, fmt.Errorf("couldn't parse value %s: %s", s, err)
   148  	}
   149  	return i, nil
   150  }