Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Unlimited hard ulimit with soft limit not supported #39125

Open
jeblair opened this issue Apr 22, 2019 · 3 comments · Fixed by docker/cli#1844
Open

Unlimited hard ulimit with soft limit not supported #39125

jeblair opened this issue Apr 22, 2019 · 3 comments · Fixed by docker/cli#1844
Labels
area/cli area/runtime kind/bug Bugs are bugs. The cause may or may not be known at triage time so debugging may be needed.

Comments

@jeblair
Copy link

jeblair commented Apr 22, 2019

Description

When specifying a ulimit, it is not possible to set a soft limit and an unlimited hard limit.

Steps to reproduce the issue:

docker run --ulimit stack=8192:-1

Describe the results you received:

invalid argument "stack=8192:-1" for "--ulimit" flag: ulimit soft limit must be less than or equal to hard limit: 8192 > -1

Describe the results you expected:

The container should start with a soft stack limit of 8192K and no hard limit.

Output of docker version:

Client:
 Version:           18.09.2
 API version:       1.39
 Go version:        go1.10.4
 Git commit:        6247962
 Built:             Tue Feb 26 23:52:23 2019
 OS/Arch:           linux/amd64
 Experimental:      false

Server:
 Engine:
  Version:          18.09.2
  API version:      1.39 (minimum version 1.12)
  Go version:       go1.10.4
  Git commit:       6247962
  Built:            Wed Feb 13 00:24:14 2019
  OS/Arch:          linux/amd64
  Experimental:     false

Output of docker info:

N/A

Additional environment details (AWS, VirtualBox, physical, etc.):
Any environment

@thaJeztah thaJeztah added area/cli area/runtime kind/bug Bugs are bugs. The cause may or may not be known at triage time so debugging may be needed. labels Apr 23, 2019
@thaJeztah
Copy link
Member

Thanks for reporting!

Some other interesting bits I found; it looks like they have to be multiplied by 1024 (kb)

(both hard and soft limit default to 8192 on the machine I tested);

docker run --rm busybox sh -c 'ulimit -S -a | grep stack && ulimit -H -a | grep stack'
-s: stack size (kb)                8192
-s: stack size (kb)                8192

Manually specifying those values, it looks like they have to be multiplied by 1024 (kb)

(omitting the grep, as it fails due to the limit);

docker run --rm --ulimit "stack=8192:8192" busybox sh -c 'ulimit -a'
-f: file size (blocks)             unlimited
-t: cpu time (seconds)             unlimited
-d: data seg size (kb)             unlimited
-s: stack size (kb)                8
-c: core file size (blocks)        0
-m: resident set size (kb)         unlimited
-l: locked memory (kb)             82000
-p: processes                      unlimited
-n: file descriptors               1048576
-v: address space (kb)             unlimited
-w: locks                          unlimited
-e: scheduling priority            0
-r: real-time priority             0

To get the original value, multiply by 1024 (8192 * 1024 = 8388608);

docker run --rm --ulimit "stack=8388608:8388608" busybox sh -c 'ulimit -S -a | grep stack && ulimit -H -a | grep stack'

-s: stack size (kb)                8192
-s: stack size (kb)                8192

I'm not sure if that's a bug, or not properly documented (but at least it's confusing), because other (non-byte values) won't do a conversion;

docker run --rm --ulimit 'nofile=1024:1048576' busybox sh -c 'ulimit -S -a | grep descriptors && ulimit -H -a | grep descriptors'
-n: file descriptors               1024
-n: file descriptors               1048576

The actual validation is done in code vendored in the Docker CLI, and from this repository: https://github.com/docker/go-units. Changing this line; https://github.com/docker/go-units/blob/d4a9b9617350c034730bc5051c605919943080bf/ulimit.go#L99-L101

if soft > *hard {
	return nil, fmt.Errorf("ulimit soft limit must be less than or equal to hard limit: %d > %d", soft, *hard)
}

To

if *hard != -1 && soft > *hard {
	return nil, fmt.Errorf("ulimit soft limit must be less than or equal to hard limit: %d > %d", soft, *hard)
}

The error goes away; I do notice that when converting those limits to an OCI-spec, those values are changed to an unsigned integer, so the -1 would get converted to "max" uint64;

moby/daemon/oci_linux.go

Lines 48 to 52 in c478553

rlimits = append(rlimits, specs.POSIXRlimit{
Type: "RLIMIT_" + strings.ToUpper(ul.Name),
Soft: uint64(ul.Soft),
Hard: uint64(ul.Hard),
})

This seems to be interpreted correctly though (with my patch applied);

docker run --rm --ulimit "stack=16777216:-1" busybox sh -c 'ulimit -S -a | grep stack && ulimit -H -a | grep stack'
-s: stack size (kb)                16384
-s: stack size (kb)                unlimited

While testing this, I found (what I think is a) a bug in busybox; for busybox, the -H/-S and -a flags look to be positional ;

docker run --rm --ulimit "stack=8388608:16777216" busybox sh -c 'ulimit -aS | grep stack && ulimit -aH | grep stack'
-s: stack size (kb)                8192
-s: stack size (kb)                8192

docker run --rm --ulimit "stack=8388608:16777216" busybox sh -c 'ulimit -Sa | grep stack && ulimit -Ha | grep stack'
-s: stack size (kb)                8192
-s: stack size (kb)                16384


docker run --rm --ulimit "stack=8388608:16777216" busybox sh -c 'ulimit -a -S | grep stack && ulimit -a -H | grep stack'
-s: stack size (kb)                8192
-s: stack size (kb)                8192


docker run --rm --ulimit "stack=8388608:16777216" busybox sh -c 'ulimit -S -a | grep stack && ulimit -H -a | grep stack'
-s: stack size (kb)                8192
-s: stack size (kb)                16384

@thaJeztah
Copy link
Member

Opened a bug-report for the busybox issue (at least, I think it's a bug); https://bugs.busybox.net/show_bug.cgi?id=11791

thaJeztah added a commit to thaJeztah/go-units that referenced this issue Apr 23, 2019
Addresses moby/moby#39125

Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
@thaJeztah
Copy link
Member

And opened a pull-request in go-units; docker/go-units#33

thaJeztah added a commit to thaJeztah/go-units that referenced this issue Apr 23, 2019
Addresses moby/moby#39125

Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
openstack-gerrit pushed a commit to openstack/openstack that referenced this issue Apr 23, 2019
* Update system-config from branch 'master'
  - Merge "Double stack size on gitea"
  - Double stack size on gitea
    
    Git can segfault and cause a gitea error due to the size of the
    openstack/openstack repo.  Give it more stack space.
    
    The hard limit is a workaround for
    moby/moby#39125
    
    Change-Id: Ibce79d8ab27af3070bf9c5f584d0d78f2b266388
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
area/cli area/runtime kind/bug Bugs are bugs. The cause may or may not be known at triage time so debugging may be needed.
Projects
None yet
Development

Successfully merging a pull request may close this issue.

2 participants