summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorLaurent Bercot <ska-skaware@skarnet.org>2023-02-26 19:08:06 +0000
committerLaurent Bercot <ska@appnovation.com>2023-02-26 19:08:06 +0000
commitef4d8c74f9342cc67421f20e4aaa4d62a911fcb8 (patch)
treec0101f833e82b2b4ff3d1f7214a9a7c2e333235d
parent96cb4bc24db14b353fd47d8d4325fd02730b6b5f (diff)
downloads6-linux-init-ef4d8c74f9342cc67421f20e4aaa4d62a911fcb8.tar.xz
Prepare for 1.1.1.0; add s6-l-i-m -R option to set hard limits
Signed-off-by: Laurent Bercot <ska@appnovation.com>
-rw-r--r--INSTALL4
-rw-r--r--NEWS7
-rw-r--r--doc/index.html6
-rw-r--r--doc/overview.html1
-rw-r--r--doc/s6-linux-init-maker.html17
-rw-r--r--doc/upgrade.html9
-rw-r--r--package/info2
-rw-r--r--src/init/rlimit.txt27
-rw-r--r--src/init/s6-linux-init-maker.c89
9 files changed, 152 insertions, 10 deletions
diff --git a/INSTALL b/INSTALL
index 9f52c44..6663a65 100644
--- a/INSTALL
+++ b/INSTALL
@@ -9,8 +9,8 @@ Build Instructions
- skalibs version 2.13.1.0 or later: https://skarnet.org/software/skalibs/
- Optional: nsss version 0.2.0.3 or later: https://skarnet.org/software/nsss/
- Optional: utmps version 0.1.2.1 or later: https://skarnet.org/software/utmps/
- - execline version 2.9.2.0 or later: https://skarnet.org/software/execline/
- - s6 version 2.11.3.0 or later: https://skarnet.org/software/s6/
+ - execline version 2.9.2.1 or later: https://skarnet.org/software/execline/
+ - s6 version 2.11.3.1 or later: https://skarnet.org/software/s6/
This software is Linux-specific. It will run on a Linux kernel,
version 2.6.32 or later. However, it should not be too hard to port to
diff --git a/NEWS b/NEWS
index 46b0dd1..f33518c 100644
--- a/NEWS
+++ b/NEWS
@@ -1,5 +1,12 @@
Changelog for s6-linux-init.
+In 1.1.1.0
+----------
+
+ - s6-linux-init-maker can now set global resource limits in the
+prepared system, via the -R option.
+
+
In 1.1.0.0
----------
diff --git a/doc/index.html b/doc/index.html
index 14230a8..e5e0408 100644
--- a/doc/index.html
+++ b/doc/index.html
@@ -80,9 +80,9 @@ programs used when you boot a system created with
<a href="s6-linux-init-maker.html">s6-linux-init-maker</a>) if you link
against the shared version of the skalibs library. </li>
<li> <a href="//skarnet.org/software/execline/">execline</a> version
-2.9.2.0 or later. It is a build-time and boot-time requirement. </li>
+2.9.2.1 or later. It is a build-time and boot-time requirement. </li>
<li> <a href="//skarnet.org/software/s6/">s6</a> version
-2.11.3.0 or later. It is a build-time and boot-time requirement. </li>
+2.11.3.1 or later. It is a build-time and boot-time requirement. </li>
</ul>
<p>
@@ -110,7 +110,7 @@ want nsswitch-like functionality:
<ul>
<li> The current released version of s6-linux-init is
-<a href="s6-linux-init-1.1.0.0.tar.gz">1.1.0.0</a>. </li>
+<a href="s6-linux-init-1.1.1.0.tar.gz">1.1.1.0</a>. </li>
<li> Alternatively, you can checkout a copy of the
<a href="//git.skarnet.org/cgi-bin/cgit.cgi/s6-linux-init/">s6-linux-init
git repository</a>:
diff --git a/doc/overview.html b/doc/overview.html
index ef01e1e..9768bf2 100644
--- a/doc/overview.html
+++ b/doc/overview.html
@@ -98,6 +98,7 @@ invariants are met:
</p>
<ul>
+ <li> Global resource limits, if any, are set on the system. </li>
<li> A tmpfs is mounted on <tt>/run</tt> - that location can be changed
at build-time via the <tt>--tmpfsdir</tt> option to configure. The rest
of this document assumes it is <tt>/run</tt>. </li>
diff --git a/doc/s6-linux-init-maker.html b/doc/s6-linux-init-maker.html
index 1390781..33bb550 100644
--- a/doc/s6-linux-init-maker.html
+++ b/doc/s6-linux-init-maker.html
@@ -61,6 +61,7 @@ machine</em>. If it is not the case, the system will fail to boot.
[ -D <em>initdefault</em> ] \
[ -n | -N ] \
[ -f <em>skeldir</em> ] \
+ [ -R <em>resource_limit_list</em> ] \
[ -C ] \
[ -B ] \
[ -S ] \
@@ -319,6 +320,22 @@ build time. This option is typically useful when distributions run
<tt>s6-linux-init-maker</tt> in packaging scripts, when preparing
files in a staging directory. </li> <br />
+ <li> <tt>-R</tt>&nbsp;<em>resource_limit_list</em>&nbsp;: declare
+global resource limits (a.k.a. "hard limits") for the system to be
+booted. <em>resource_limit_list</em> is a comma-separated list of
+instructions such as <tt>o2000</tt>, <tt>d=</tt> or <tt>c0</tt>:
+a letter followed by either the character <tt>=</tt>, which means
+unlimited, or a number, which is the value of the resource limit.
+The letter specifies the resource being addressed, as defined by
+the option letters used by
+<a href="//skarnet.org/software/s6/s6-softlimit.html">s6-softlimit</a>:
+for instance, <tt>c</tt> means core file size limit, and <tt>o</tt>
+means open fds limit. Note that unlike s6-softlimit, which only sets
+<em>soft limits</em>, i.e. process hierarchy-wide limits, the values
+given here declare <em>hard limits</em> that will be enforced for the
+whole system to be booted: it will be impossible to raise soft limits
+above these values. </li> <br />
+
<li> <tt>-C</tt>&nbsp;: create a set of scripts that is suitable
for running <em>in a container</em>. This modifies some behaviours:
<ul>
diff --git a/doc/upgrade.html b/doc/upgrade.html
index e1799f1..18066c7 100644
--- a/doc/upgrade.html
+++ b/doc/upgrade.html
@@ -18,6 +18,15 @@
<h1> What has changed in s6-linux-init </h1>
+<h2> in 1.1.1.0 </h2>
+
+<ul>
+ <li> <a href="//skarnet.org/software/execline/">execline</a>
+dependency bumped to 2.9.2.1. </li>
+ <li> <a href="//skarnet.org/software/s6/">s6</a>
+dependency bumped to 2.11.3.1. </li>
+</ul>
+
<h2> in 1.1.0.0 </h2>
<ul>
diff --git a/package/info b/package/info
index ed1e732..9ce90b5 100644
--- a/package/info
+++ b/package/info
@@ -1,4 +1,4 @@
package=s6-linux-init
-version=1.1.0.0
+version=1.1.1.0
category=admin
package_macro_name=S6_LINUX_INIT
diff --git a/src/init/rlimit.txt b/src/init/rlimit.txt
new file mode 100644
index 0000000..70e7004
--- /dev/null
+++ b/src/init/rlimit.txt
@@ -0,0 +1,27 @@
+s6-l-i-m -R argument parser:
+
+class | 0 1 2 3 4 5
+st\ev | \0 letter = 0-9 , other
+
+
+START | g
+0 | END ARG X X START X
+
+ARG | = m
+1 | X X WAIT SCAN X X
+
+SCAN | s s
+2 | END X X SCAN START X
+
+WAIT |
+3 | END X X X START X
+
+END = 4, X = 5
+
+3 bits state
+4 bits action
+
+0x10 g print letter
+0x20 = set max
+0x40 m mark
+0x80 s scan from mark
diff --git a/src/init/s6-linux-init-maker.c b/src/init/s6-linux-init-maker.c
index b5edaaf..1a8827b 100644
--- a/src/init/s6-linux-init-maker.c
+++ b/src/init/s6-linux-init-maker.c
@@ -26,7 +26,7 @@
#include "defaults.h"
#include "initctl.h"
-#define USAGE "s6-linux-init-maker [ -c basedir ] [ -u log_user ] [ -G early_getty_cmd ] [ -1 ] [ -L ] [ -p initial_path ] [ -m initial_umask ] [ -t timestamp_style ] [ -d slashdev ] [ -s env_store ] [ -e initial_envvar ... ] [ -q default_grace_time ] [ -D initdefault ] [ -n | -N ] [ -f skeldir ] [ -C ] [ -B ] dir"
+#define USAGE "s6-linux-init-maker [ -c basedir ] [ -u log_user ] [ -G early_getty_cmd ] [ -1 ] [ -L ] [ -p initial_path ] [ -m initial_umask ] [ -t timestamp_style ] [ -d slashdev ] [ -s env_store ] [ -e initial_envvar ... ] [ -q default_grace_time ] [ -D initdefault ] [ -n | -N ] [ -f skeldir ] [ -R resourcelimits ] [ -C ] [ -B ] [ -S ] dir"
#define dieusage() strerr_dieusage(100, USAGE)
#define dienomem() strerr_diefu1sys(111, "stralloc_catb") ;
@@ -51,6 +51,7 @@ static int innssync = 0 ;
static int nologger = 0 ;
static uid_t myuid = -1 ;
static gid_t mygid = -1 ;
+static stralloc ressa = STRALLOC_ZERO ;
typedef int writetobuf_func (buffer *, char const *) ;
typedef writetobuf_func *writetobuf_func_ref ;
@@ -238,8 +239,13 @@ static int sig_script (buffer *b, char const *option)
static inline int stage1_script (buffer *b, char const *data)
{
size_t sabase = satmp.len ;
- if (!put_shebang_options(b, "-S0")
- || buffer_puts(b, S6_LINUX_INIT_EXTBINPREFIX "s6-linux-init -c ") < 0
+ if (!put_shebang_options(b, "-S0")) return 0 ;
+ if (ressa.len)
+ {
+ if (buffer_puts(b, S6_EXTBINPREFIX "s6-softlimit -h ") < 0
+ || buffer_put(b, ressa.s, ressa.len) < 0) goto err ;
+ }
+ if (buffer_puts(b, S6_LINUX_INIT_EXTBINPREFIX "s6-linux-init -c ") < 0
|| !string_quote(&satmp, robase, strlen(robase))) return 0 ;
if (buffer_put(b, satmp.s + sabase, satmp.len - sabase) < 0) goto err ;
satmp.len = sabase ;
@@ -575,6 +581,80 @@ static inline void make_bins (char const *base)
if (!inns) auto_exec(base, "bin/telinit", "s6-linux-init-telinit") ;
}
+static uint8_t rclass (char c)
+{
+ switch (c)
+ {
+ case 0 : return 0 ;
+ case 'a' :
+ case 'c' :
+ case 'd' :
+ case 'f' :
+ case 'l' :
+ case 'm' :
+ case 'o' :
+ case 'p' :
+ case 'r' :
+ case 's' :
+ case 't' : return 1 ;
+ case '=' : return 2 ;
+ case '0' :
+ case '1' :
+ case '2' :
+ case '3' :
+ case '4' :
+ case '5' :
+ case '6' :
+ case '7' :
+ case '8' :
+ case '9' : return 3 ;
+ case ',' :
+ case ';' :
+ case ' ' : return 4 ;
+ default : return 5 ;
+ }
+}
+
+static void parse_resources (stralloc *sa, char const *s)
+{
+ static uint8_t const table[4][6] =
+ {
+ { 0x04, 0x11, 0x05, 0x05, 0x00, 0x05 },
+ { 0x05, 0x05, 0x23, 0x42, 0x05, 0x05 },
+ { 0x84, 0x05, 0x05, 0x02, 0x80, 0x05 },
+ { 0x04, 0x05, 0x05, 0x05, 0x00, 0x05 }
+ } ;
+ char const *m = s ;
+ uint8_t state = 0 ;
+ char tmp[UINT64_FMT] ;
+ sa->len = 0 ;
+ while (state < 4)
+ {
+ uint8_t c = table[state][rclass(*s)] ;
+ state = c & 0x07 ;
+ if (c & 0x10)
+ {
+ tmp[0] = '-' ; tmp[1] = *s ;
+ if (!stralloc_catb(sa, tmp, 2)) dienomem() ;
+ }
+ if (c & 0x20) if (!stralloc_catb(sa, "= ", 2)) dienomem() ;
+ if (c & 0x40) m = s ;
+ if (c & 0x80)
+ {
+ uint64_t u ;
+ if (s - m >= UINT64_FMT) strerr_dief1x(100, "resource limit out of range") ;
+ memcpy(tmp, m, s - m) ;
+ tmp[s - m] = 0 ;
+ if (!uint640_scan(tmp, &u)) strerr_dief1x(100, "resource limit out of range") ;
+ tmp[s - m] = ' ' ;
+ if (!stralloc_catb(sa, tmp, s - m + 1)) dienomem() ;
+ }
+ s++ ;
+ }
+ if (state > 4) strerr_dief1x(100, "syntax error in resource limit string") ;
+ if (sa->len) if (!stralloc_catb(sa, "--\n", 3)) dienomem() ;
+}
+
int main (int argc, char const *const *argv, char const *const *envp)
{
PROG = "s6-linux-init-maker" ;
@@ -582,7 +662,7 @@ int main (int argc, char const *const *argv, char const *const *envp)
subgetopt l = SUBGETOPT_ZERO ;
for (;;)
{
- int opt = subgetopt_r(argc, argv, "c:u:G:1Lp:m:t:d:s:e:E:q:D:nNf:CBS", &l) ;
+ int opt = subgetopt_r(argc, argv, "c:u:G:1Lp:m:t:d:s:e:E:q:D:nNf:R:CBS", &l) ;
if (opt == -1) break ;
switch (opt)
{
@@ -602,6 +682,7 @@ int main (int argc, char const *const *argv, char const *const *envp)
case 'n' : mounttype = 2 ; break ;
case 'N' : mounttype = 0 ; break ;
case 'f' : skeldir = l.arg ; break ;
+ case 'R' : parse_resources(&ressa, l.arg) ; break ;
case 'C' : inns = 1 ; break ;
case 'B' : nologger = 1 ; break ;
case 'S' : innssync = 1 ; break ;