gtsocial-umbx

Unnamed repository; edit this file 'description' to name the repository.
Log | Files | Refs | README | LICENSE

ulimit.go (3189B)


      1 package units
      2 
      3 import (
      4 	"fmt"
      5 	"strconv"
      6 	"strings"
      7 )
      8 
      9 // Ulimit is a human friendly version of Rlimit.
     10 type Ulimit struct {
     11 	Name string
     12 	Hard int64
     13 	Soft int64
     14 }
     15 
     16 // Rlimit specifies the resource limits, such as max open files.
     17 type Rlimit struct {
     18 	Type int    `json:"type,omitempty"`
     19 	Hard uint64 `json:"hard,omitempty"`
     20 	Soft uint64 `json:"soft,omitempty"`
     21 }
     22 
     23 const (
     24 	// magic numbers for making the syscall
     25 	// some of these are defined in the syscall package, but not all.
     26 	// Also since Windows client doesn't get access to the syscall package, need to
     27 	//	define these here
     28 	rlimitAs         = 9
     29 	rlimitCore       = 4
     30 	rlimitCPU        = 0
     31 	rlimitData       = 2
     32 	rlimitFsize      = 1
     33 	rlimitLocks      = 10
     34 	rlimitMemlock    = 8
     35 	rlimitMsgqueue   = 12
     36 	rlimitNice       = 13
     37 	rlimitNofile     = 7
     38 	rlimitNproc      = 6
     39 	rlimitRss        = 5
     40 	rlimitRtprio     = 14
     41 	rlimitRttime     = 15
     42 	rlimitSigpending = 11
     43 	rlimitStack      = 3
     44 )
     45 
     46 var ulimitNameMapping = map[string]int{
     47 	//"as":         rlimitAs, // Disabled since this doesn't seem usable with the way Docker inits a container.
     48 	"core":       rlimitCore,
     49 	"cpu":        rlimitCPU,
     50 	"data":       rlimitData,
     51 	"fsize":      rlimitFsize,
     52 	"locks":      rlimitLocks,
     53 	"memlock":    rlimitMemlock,
     54 	"msgqueue":   rlimitMsgqueue,
     55 	"nice":       rlimitNice,
     56 	"nofile":     rlimitNofile,
     57 	"nproc":      rlimitNproc,
     58 	"rss":        rlimitRss,
     59 	"rtprio":     rlimitRtprio,
     60 	"rttime":     rlimitRttime,
     61 	"sigpending": rlimitSigpending,
     62 	"stack":      rlimitStack,
     63 }
     64 
     65 // ParseUlimit parses and returns a Ulimit from the specified string.
     66 func ParseUlimit(val string) (*Ulimit, error) {
     67 	parts := strings.SplitN(val, "=", 2)
     68 	if len(parts) != 2 {
     69 		return nil, fmt.Errorf("invalid ulimit argument: %s", val)
     70 	}
     71 
     72 	if _, exists := ulimitNameMapping[parts[0]]; !exists {
     73 		return nil, fmt.Errorf("invalid ulimit type: %s", parts[0])
     74 	}
     75 
     76 	var (
     77 		soft int64
     78 		hard = &soft // default to soft in case no hard was set
     79 		temp int64
     80 		err  error
     81 	)
     82 	switch limitVals := strings.Split(parts[1], ":"); len(limitVals) {
     83 	case 2:
     84 		temp, err = strconv.ParseInt(limitVals[1], 10, 64)
     85 		if err != nil {
     86 			return nil, err
     87 		}
     88 		hard = &temp
     89 		fallthrough
     90 	case 1:
     91 		soft, err = strconv.ParseInt(limitVals[0], 10, 64)
     92 		if err != nil {
     93 			return nil, err
     94 		}
     95 	default:
     96 		return nil, fmt.Errorf("too many limit value arguments - %s, can only have up to two, `soft[:hard]`", parts[1])
     97 	}
     98 
     99 	if *hard != -1 {
    100 		if soft == -1 {
    101 			return nil, fmt.Errorf("ulimit soft limit must be less than or equal to hard limit: soft: -1 (unlimited), hard: %d", *hard)
    102 		}
    103 		if soft > *hard {
    104 			return nil, fmt.Errorf("ulimit soft limit must be less than or equal to hard limit: %d > %d", soft, *hard)
    105 		}
    106 	}
    107 
    108 	return &Ulimit{Name: parts[0], Soft: soft, Hard: *hard}, nil
    109 }
    110 
    111 // GetRlimit returns the RLimit corresponding to Ulimit.
    112 func (u *Ulimit) GetRlimit() (*Rlimit, error) {
    113 	t, exists := ulimitNameMapping[u.Name]
    114 	if !exists {
    115 		return nil, fmt.Errorf("invalid ulimit name %s", u.Name)
    116 	}
    117 
    118 	return &Rlimit{Type: t, Soft: uint64(u.Soft), Hard: uint64(u.Hard)}, nil
    119 }
    120 
    121 func (u *Ulimit) String() string {
    122 	return fmt.Sprintf("%s=%d:%d", u.Name, u.Soft, u.Hard)
    123 }