From 91ea846a6f05e9a57b2b3bc3b56a94e0026c5618 Mon Sep 17 00:00:00 2001 From: Laurent Bercot Date: Sat, 4 May 2019 19:57:36 +0000 Subject: Add -n and -N options to s6-l-i and s6-l-i-m --- doc/s6-linux-init-maker.html | 33 ++++++++++++++++++++++++++++++++- doc/s6-linux-init.html | 19 +++++++++++-------- src/init/s6-linux-init-maker.c | 20 ++++++++++++++++---- src/init/s6-linux-init.c | 31 +++++++++++++++++++++++-------- 4 files changed, 82 insertions(+), 21 deletions(-) diff --git a/doc/s6-linux-init-maker.html b/doc/s6-linux-init-maker.html index 6c52d32..02fd15d 100644 --- a/doc/s6-linux-init-maker.html +++ b/doc/s6-linux-init-maker.html @@ -59,6 +59,7 @@ machine. If it is not the case, the system will fail to boot. [ -e initial_envvar ] ... \ [ -q finalsleeptime ] \ [ -D initdefault ] \ + [ -n | -N ] [ -U utmp_user ] \ dir @@ -169,7 +170,7 @@ is defined.

  • -1 : make it so that all the messages that are sent to the catch-all logger (i.e. all the error messages that are not caught by a dedicated logger, as well as the output from rc.init, -runlevel and rc.shutdown, +runlevel and rc.shutdown) are also copied to /dev/console. (Timestamps are not copied to /dev/console.) This is generally useful to debug a system at a glance, but if a failing program keeps sending @@ -264,6 +265,36 @@ sysvinit behaviour) or default (OpenRC behaviour). Default is command line, it will be interpreted as the runlevel to boot the system on, and will override the default given here.
  • +

  • -n : at boot time, assume that a tmpfs is already +present on /run (or the argument that was given to the +--tmpfsdir configure option at build time) and that its +contents are essential. Instead of unmounting /run then +mounting a tmpfs on it, s6-linux-init +will simply remount /run. This option is useful when +s6-linux-init is used on a distribution that imposes its initramfs +and said initramfs writes data to /run that is then used +by the distribution's initialization scripts. (An initramfs should +normally be transparent and leave no trace in the filesystem; +unfortunately, a lot of distributions do not care.) By default, +/run will be unmounted at boot time (just in case), and +then a tmpfs will be mounted on it. Do not use +this option if you are not sure: failure to remount /run +will cause init to die and the kernel to panic. This option is +incompatible with the -N option.
  • + +

  • -N : at boot time, do not perform +mounting/unmounting/remounting on /run (or the tmpfsdir +declared at build time) at all. By default, +a tmpfs is mounted on /run at boot time. This option is +useful when s6-linux-init is used to boot on an initramfs that +will remain the de facto rootfs of the system (which is the case +for instance in certain live CDs or certain embedded devices), in +which case the rootfs is already read-write and in RAM and mounting +an additional tmpfs is unnecessary. Do not use this +option if your rootfs is read-only: failure to write to /run +will cause init to die and the kernel to panic. This option is +incompatible with the -n option.
  • +

  • -U utmp_user : this option is only available when the s6-linux-init package has been built with the --enable-utmps configure option, that enables support for the diff --git a/doc/s6-linux-init.html b/doc/s6-linux-init.html index 31014d6..f57adae 100644 --- a/doc/s6-linux-init.html +++ b/doc/s6-linux-init.html @@ -27,7 +27,7 @@ and execs into s6-svscan.

    Interface

    -     s6-linux-init [ -c basedir ] [ -p initial_path ] [ -s env_store ] [ -m umask ] [ -d dev_style ] [ -D initdefault ] [ args... ]
    +     s6-linux-init [ -c basedir ] [ -p initial_path ] [ -s env_store ] [ -m umask ] [ -d dev_style ] [ -D initdefault ] [ -n | -N ] [ args... ]
     

    Early preparation

    @@ -79,12 +81,13 @@ operations:
  • It chdirs to /.
  • It sets the umask to initial_umask.
  • It becomes a session leader.
  • -
  • It mounts a devtmpfs on /dev, if necessary.
  • +
  • It mounts a devtmpfs on slashdev, if requested.
  • It uses /dev/null as its stdin (instead of /dev/console). /dev/console is still used, for now, as stdout and stderr.
  • It unmounts /run (or the directory you have given to the ---tmpfsdir configure option at package build time), just in case.
  • -
  • It creates a tmpfs on /run (or your chosen tmpfsdir).
  • +--tmpfsdir configure option at package build time), just in case; +then it creates a tmpfs on it. Alternatively, it remounts /run, +or does not touch it at all.
  • It copies the whole basedir/run-image hierarchy to /run (or your chosen tmpfsdir).
  • It reads the initial environment from basedir/env.
  • diff --git a/src/init/s6-linux-init-maker.c b/src/init/s6-linux-init-maker.c index 434e29f..1005811 100644 --- a/src/init/s6-linux-init-maker.c +++ b/src/init/s6-linux-init-maker.c @@ -28,12 +28,12 @@ #ifdef S6_LINUX_INIT_UTMPD_PATH # include -# 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 ] [ -U utmp_user ] dir" -# define OPTION_STRING "c:u:G:1Lp:m:t:d:s:e:E:q:U:D:" +# 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 ] [ -U utmp_user ] dir" +# define OPTION_STRING "c:u:G:1Lp:m:t:d:s:e:E:q:D:nNU:" # define UTMPS_DIR "utmps" #else -# 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 ] dir" -# define OPTION_STRING "c:u:G:1Lp:m:t:d:s:e:E:q:D:" +# 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 ] dir" +# define OPTION_STRING "c:u:G:1Lp:m:t:d:s:e:E:q:D:nN" #endif #define dieusage() strerr_dieusage(100, USAGE) @@ -51,6 +51,7 @@ static char const *initdefault = 0 ; static unsigned int initial_umask = 0022 ; static unsigned int timestamp_style = 1 ; static unsigned int finalsleep = 3000 ; +static int mounttype = 1 ; static int console = 0 ; static int logouthookd = 0 ; @@ -233,6 +234,15 @@ static inline int stage1_script (buffer *b, char const *data) if (buffer_put(b, satmp.s + sabase, satmp.len - sabase) < 0) goto err ; satmp.len = sabase ; } + if (mounttype == 2) + { + if (buffer_puts(b, " -n") < 0) return 0 ; + } + else if (!mounttype) + { + if (buffer_puts(b, " -N") < 0) return 0 ; + } + if (buffer_puts(b, "\n") < 0) return 0 ; (void)data ; return 1 ; @@ -575,6 +585,8 @@ int main (int argc, char const *const *argv, char const *const *envp) case 'e' : if (!stralloc_catb(&satmp, l.arg, strlen(l.arg) + 1)) dienomem() ; break ; case 'q' : if (!uint0_scan(l.arg, &finalsleep)) dieusage() ; break ; case 'D' : initdefault = l.arg ; break ; + case 'n' : mounttype = 2 ; break ; + case 'N' : mounttype = 0 ; break ; #ifdef S6_LINUX_INIT_UTMPD_PATH case 'U' : utmp_user = l.arg ; break ; #endif diff --git a/src/init/s6-linux-init.c b/src/init/s6-linux-init.c index b6113a9..e322fa4 100644 --- a/src/init/s6-linux-init.c +++ b/src/init/s6-linux-init.c @@ -23,7 +23,7 @@ #include "defaults.h" #include "initctl.h" -#define USAGE "s6-linux-init [ -c basedir ] [ -p initpath ] [ -s envdumpdir ] [ -m umask ] [ -d devtmpfs ] [ -D initdefault ]" +#define USAGE "s6-linux-init [ -c basedir ] [ -p initpath ] [ -s envdumpdir ] [ -m umask ] [ -d devtmpfs ] [ -D initdefault ] [ -n | -N ]" #define dieusage() strerr_dieusage(100, USAGE) #define BANNER "\n s6-linux-init version " S6_LINUX_INIT_VERSION "\n\n" @@ -68,6 +68,7 @@ int main (int argc, char const **argv, char const *const *envp) char const *slashdev = 0 ; char const *envdumpdir = 0 ; char const *initdefault = "default" ; + int mounttype = 1 ; stralloc envmodifs = STRALLOC_ZERO ; PROG = "s6-linux-init" ; @@ -82,7 +83,7 @@ int main (int argc, char const **argv, char const *const *envp) subgetopt_t l = SUBGETOPT_ZERO ; for (;;) { - int opt = subgetopt_r(argc, argv, "c:p:s:m:d:D:", &l) ; + int opt = subgetopt_r(argc, argv, "c:p:s:m:d:D:nN", &l) ; if (opt == -1) break ; switch (opt) { @@ -92,6 +93,8 @@ int main (int argc, char const **argv, char const *const *envp) case 'm' : if (!uint0_oscan(l.arg, &mask)) dieusage() ; break ; case 'd' : slashdev = l.arg ; break ; case 'D' : initdefault = l.arg ; break ; + case 'n' : mounttype = 2 ; break ; + case 'N' : mounttype = 0 ; break ; default : dieusage() ; } } @@ -121,14 +124,26 @@ int main (int argc, char const **argv, char const *const *envp) || fd_move(2, 0) == -1) return 111 ; } if (open("/dev/null", O_RDONLY)) strerr_diefu1sys(111, "open /dev/null") ; - - if (umount(S6_LINUX_INIT_TMPFS) == -1) + + if (mounttype) { - if (errno != EINVAL) - strerr_warnwu1sys("umount " S6_LINUX_INIT_TMPFS) ; + if (mounttype == 2) + { + if (mount("tmpfs", S6_LINUX_INIT_TMPFS, "tmpfs", MS_REMOUNT | MS_NODEV | MS_NOSUID, "mode=0755") == -1) + strerr_diefu1sys(111, "remount " S6_LINUX_INIT_TMPFS) ; + } + else + { + if (umount(S6_LINUX_INIT_TMPFS) == -1) + { + if (errno != EINVAL) + strerr_warnwu1sys("umount " S6_LINUX_INIT_TMPFS) ; + } + if (mount("tmpfs", S6_LINUX_INIT_TMPFS, "tmpfs", MS_NODEV | MS_NOSUID, "mode=0755") == -1) + strerr_diefu1sys(111, "mount tmpfs on " S6_LINUX_INIT_TMPFS) ; + } } - if (mount("tmpfs", S6_LINUX_INIT_TMPFS, "tmpfs", MS_NODEV | MS_NOSUID, "mode=0755") == -1) - strerr_diefu1sys(111, "mount tmpfs on " S6_LINUX_INIT_TMPFS) ; + { size_t dirlen = strlen(basedir) ; char fn[dirlen + 1 + (sizeof(RUNIMAGE) > sizeof(ENVSTAGE1) ? sizeof(RUNIMAGE) : sizeof(ENVSTAGE1))] ; -- cgit v1.3.1