Gentoo Websites Logo
Go to: Gentoo Home Documentation Forums Lists Bugs Planet Store Wiki Get Gentoo!

Bug 763891

Summary: app-containers/docker: runscript defines default ulimit options that depend on bash
Product: Gentoo Linux Reporter: kfm
Component: Current packagesAssignee: William Hubbs <williamh>
Status: CONFIRMED ---    
Severity: normal CC: awkravchuk, gyakovlev
Priority: Normal    
Version: unspecified   
Hardware: All   
OS: Linux   
See Also: https://bugs.gentoo.org/show_bug.cgi?id=739274
https://bugs.gentoo.org/show_bug.cgi?id=836791
https://bugs.gentoo.org/show_bug.cgi?id=903775
Whiteboard:
Package list:
Runtime testing required: ---
Bug Depends on:    
Bug Blocks: 609070    
Attachments: docker.initd
docker.initd-r1

Description kfm 2021-01-05 14:13:54 UTC
As discovered in the course of investigating bug 739274, the OpenRC runscript for docker defines a set of default options for the ulimit builtin which assume that the running shell is bash. The original reporter was not initially aware that docker was the cause, and I am now reporting this issue on his behalf.

Such an assumption is unacceptable for several reasons. Firstly, openrc-run(8) makes use of sh(1), except in the case that openrc was built with USE="bash". Secondly, it cannot be assumed that sh(1) is bash, even though it is by default in Gentoo. Thirdly, POSIX only defines one option for the ulimit builtin, which is -f and that's used for setting RLIMIT_FSIZE. All other options are non-standard, and no implementation of the POSIX Shell Command Language is under any obligation to implement them. Fourthly, even where a sh(1) implementation does implement any non-standard options, they will inevitably differ. For example, bash supports the -u option to define RLIMIT_NPROC but dash supports the -p option for this purpose.

In short, if the runscript is going to continue to define bash-specific ulimit options then it should make a point of running bash. I shall attach a revised runscript which addresses the issue in this manner.

Note that the original bug stands on its own merits because OpenRC has weak error reporting in the case that the ulimit command fails, presenting an opportunity to improve it.
Comment 1 kfm 2021-01-05 14:19:16 UTC
Created attachment 681301 [details]
docker.initd

This is a replacement docker.initd file which differs by spawning an instance of bash to set the rlimits before replacing itself with docker. Andrew, would you mind testing this?
Comment 2 kfm 2021-01-05 14:28:31 UTC
Created attachment 681307 [details]
docker.initd-r1

First one contained a silly typo. Try this one.
Comment 3 Andrew 2021-01-05 15:20:15 UTC
Oh, I've already rebuilt my openrc with +bash, but sure, why not. I'll report the results upon the next boot (running it directly yields no problems). Thanks Kerin!
Comment 4 kfm 2021-01-05 15:29:42 UTC
(In reply to Andrew from comment #3)
> Oh, I've already rebuilt my openrc with +bash, but sure, why not. I'll
> report the results upon the next boot (running it directly yields no
> problems). Thanks Kerin!

Note that, after starting docker with the revised runscript, you may test that the intended rlimits have taken effect by running:

    read -r pid < /run/docker.pid && cat "/proc/$pid/limits"

Assuming that you haven't defined and customised DOCKER_ULIMIT in the conf.d file, you should see that the reported limits reflect the intention of the default options (-c unlimited -n 1048576 -u unlimited). Moreover, it should do so regardless of which /bin/sh provider you are using.
Comment 5 William Hubbs gentoo-dev 2021-01-05 15:53:50 UTC
I recommend opening a bug upstream and asking them to remove
the non-posix options from the init script. The init script should not,
by default, use non-posix ulimit options.

They could document other recommended options in docker.confd.

Which options are non-posix? Also do you want to open the bug or should
I?

Thanks,

William
Comment 6 kfm 2021-01-05 17:21:07 UTC
As explained in the opening comment and in bug 739274, -f is the only option specified by POSIX. If one is to be serious about POSIX conformance, one must walk the walk, not just talk the talk. There is simply no sugar-coating the fact that there is only one standard option and that there is no generalised mechanism allowing for OpenRC runscripts to assert rlimits in a fashion that is independent of the shell. Other init systems address this issue by taking direct responsibility for defining rlimits - such as systemd - or by offering helpers - such as s6 with its s6-softlimit utility.

I do sometimes file bugs upstream but won't be doing so on this occasion. You suggest that it might be possible to define equivalent rc_ulimit options in the conf.d file for some of the more popular shells. This is simply not feasible. Let's take dash as an example. The present set of options can be made to work with two caveats. Firstly, -u must be changed to -p. I did mention this in the other bug. Secondly, one _cannot_ overload ulimit with multiple option/value pairs. Instead, one would have to run three consecutive ulimit commands, like so:-

    ulimit -c unlimited && ulimit -n 1048576 && ulimit -p unlimited

All of this should amply demonstrate that OpenRC's ulimit support is useless outside of the confines of bash. Even putting aside the obvious issue of option portability, OpenRC has no expectation that it might need to run ulimit more than once, nor does it know how to do so. Perhaps now you can understand why the attached runscript compromises by having bash set the rlimits. If there were an obviously better option, I would have taken it.
Comment 7 Andrew 2021-01-06 05:23:05 UTC
(In reply to Kerin Millar from comment #2)
> Created attachment 681307 [details]
> docker.initd-r1
> 
> First one contained a silly typo. Try this one.

So I've tried this init script (with openrc -bash flag) and Docker started properly with correct limits.
Comment 8 kfm 2021-01-07 16:46:31 UTC
(In reply to Andrew from comment #7)
> So I've tried this init script (with openrc -bash flag) and Docker started
> properly with correct limits.

Good. As bash is part of @system, I think that it is a reasonable solution until such time as OpenRC offers a shell-independent way of defining resource limits.
Comment 9 kfm 2021-02-24 06:26:02 UTC
As an aside, I noticed something interesting about the way in which the ulimit builtin operates in bash. It internally defines all possible rlimits but calculates the options supported by the platform during runtime. That means that the option parser can reject options based on the platform, though the documentation and builtin help always imply that all are recognisable, if not actionable.

For example:

$ help ulimit | grep -- -T
      -T        the maximum number of threads
$ ulimit -T
-bash: ulimit: -T: invalid option
ulimit: usage: ulimit [-SHabcdefiklmnpqrstuvxPT] [limit]
Comment 10 Esteve Varela Colominas 2021-08-23 10:20:20 UTC
Can confirm this issue, the attached docker.initd works wonderfully.