github.com/yuanlv/docker@v1.8.1/pkg/ulimit/ulimit.go (about) 1 package ulimit 2 3 import ( 4 "fmt" 5 "strconv" 6 "strings" 7 ) 8 9 // Human friendly version of Rlimit 10 type Ulimit struct { 11 Name string 12 Hard int64 13 Soft int64 14 } 15 16 type Rlimit struct { 17 Type int `json:"type,omitempty"` 18 Hard uint64 `json:"hard,omitempty"` 19 Soft uint64 `json:"soft,omitempty"` 20 } 21 22 const ( 23 // magic numbers for making the syscall 24 // some of these are defined in the syscall package, but not all. 25 // Also since Windows client doesn't get access to the syscall package, need to 26 // define these here 27 RLIMIT_AS = 9 28 RLIMIT_CORE = 4 29 RLIMIT_CPU = 0 30 RLIMIT_DATA = 2 31 RLIMIT_FSIZE = 1 32 RLIMIT_LOCKS = 10 33 RLIMIT_MEMLOCK = 8 34 RLIMIT_MSGQUEUE = 12 35 RLIMIT_NICE = 13 36 RLIMIT_NOFILE = 7 37 RLIMIT_NPROC = 6 38 RLIMIT_RSS = 5 39 RLIMIT_RTPRIO = 14 40 RLIMIT_RTTIME = 15 41 RLIMIT_SIGPENDING = 11 42 RLIMIT_STACK = 3 43 ) 44 45 var ulimitNameMapping = map[string]int{ 46 //"as": RLIMIT_AS, // Disbaled since this doesn't seem usable with the way Docker inits a container. 47 "core": RLIMIT_CORE, 48 "cpu": RLIMIT_CPU, 49 "data": RLIMIT_DATA, 50 "fsize": RLIMIT_FSIZE, 51 "locks": RLIMIT_LOCKS, 52 "memlock": RLIMIT_MEMLOCK, 53 "msgqueue": RLIMIT_MSGQUEUE, 54 "nice": RLIMIT_NICE, 55 "nofile": RLIMIT_NOFILE, 56 "nproc": RLIMIT_NPROC, 57 "rss": RLIMIT_RSS, 58 "rtprio": RLIMIT_RTPRIO, 59 "rttime": RLIMIT_RTTIME, 60 "sigpending": RLIMIT_SIGPENDING, 61 "stack": RLIMIT_STACK, 62 } 63 64 func Parse(val string) (*Ulimit, error) { 65 parts := strings.SplitN(val, "=", 2) 66 if len(parts) != 2 { 67 return nil, fmt.Errorf("invalid ulimit argument: %s", val) 68 } 69 70 if _, exists := ulimitNameMapping[parts[0]]; !exists { 71 return nil, fmt.Errorf("invalid ulimit type: %s", parts[0]) 72 } 73 74 limitVals := strings.SplitN(parts[1], ":", 2) 75 if len(limitVals) > 2 { 76 return nil, fmt.Errorf("too many limit value arguments - %s, can only have up to two, `soft[:hard]`", parts[1]) 77 } 78 79 soft, err := strconv.ParseInt(limitVals[0], 10, 64) 80 if err != nil { 81 return nil, err 82 } 83 84 hard := soft // in case no hard was set 85 if len(limitVals) == 2 { 86 hard, err = strconv.ParseInt(limitVals[1], 10, 64) 87 } 88 if soft > hard { 89 return nil, fmt.Errorf("ulimit soft limit must be less than or equal to hard limit: %d > %d", soft, hard) 90 } 91 92 return &Ulimit{Name: parts[0], Soft: soft, Hard: hard}, nil 93 } 94 95 func (u *Ulimit) GetRlimit() (*Rlimit, error) { 96 t, exists := ulimitNameMapping[u.Name] 97 if !exists { 98 return nil, fmt.Errorf("invalid ulimit name %s", u.Name) 99 } 100 101 return &Rlimit{Type: t, Soft: uint64(u.Soft), Hard: uint64(u.Hard)}, nil 102 } 103 104 func (u *Ulimit) String() string { 105 return fmt.Sprintf("%s=%d:%d", u.Name, u.Soft, u.Hard) 106 }