Hi,

On Wed, 1 Feb 2023 11:43:43 +0100
Andras Korn <korn-debb...@elan.rulez.org> wrote:


> /etc/runit/2 ships with this snippet:
> 
> mkdir -p /run/runit/supervise
> mkdir -p /run/runit/sv
> mount -t tmpfs -o size=20M,mode=0755 runtimesv /run/runit/sv
> cp -a /etc/sv/* /run/runit/sv/  #TODO do this with
> 'CPSV_DIR=/run/runit/sv cpsv --sync'
> 
> If runit is used in an unprivileged container,
with runit you mean runit as init or simply respawn runsvdir via stage
2?

The mount can be moved to stage 1, where other mount invocations already
happen; however this will cause a relevant difference when runit is
used as init vs when only stage 2/runsvdir is run..

> the mount command may
> fail. Currently this is just a cosmetic problem (/lib/runit/sv will
> not be a separate filesystem and an error will be printed), but
> please don't start depending on this mount succeeding.

Noted; that was a preliminary step for a development that didn't
happen so far (because of the complexity, the freeze approaching and
also because of your comments in #1022837); for now I'm just removing or
commenting those lines, for the future (after bookworm releaee) I still
have to think about it.
> 
> Please also provide some reasoning (e.g. in a README.Debian file) why
> you're doing this at all, what the motivation is.

I'm not going to write a README.Debian for something that is not there
(yet), but I'm providing one here:

 ---------------------------RATIONALE---------------------------------

> mount -t tmpfs -o size=20M,mode=0755 runtimesv /run/runit/sv
the idea is to have a copy of services there and to run services there,
like /etc/service points to /etc/runit/runsvdir/deafult.run that
contains links to directories in /run/runit/sv/

without that mount line:
Problem 1: run is mounted 'noexec', so each runsv fails
Problem 2: there are mechanism (cpsv) that copy services in /run
     and by limiting the size I want to avoid that an abuse of such
     mechanism could result in eating all space in /run mount (very
     unlikely but still..)

Reasons why I'm thinking of running services in /run/runit/sv/ :

A) anything in /etc/sv is a conffile, so special care is needed when
  upgrade happens to detect and not overwrite local changes. That is
  handled by dpkg or ucf, but they work on files, while a service for
  runit is a directory. I think ideally the entire service should be
  considered locally modified if the run file (or finish, or control/*
  and probably also log/run) has local changes.
  I can think of many ways to break a service by retaining the local
  version of a run file while finish or control/* are changed/upgraded.
  

B) related to A, but different problem: think of what happens if a
  foo service crashes while dpkg is upgrading (file by file) the service
  directory: the automatic restart performed by runsv can exec a mix of
  old and new files inside foo directory, with unexpected results like
  in A, but temporary (only during the upgrade).
  Ideally the entire service directory should be updated atomically but
  that requires to address the old.directory with a symlink, creating a
  new.directory on upgrade and swap the symlink old-->new.
  
Also a plus would be a setup that works on a system where /etc is
stateless or mounted readonly.

As a possible solution to A and B I thought something like:

A 3 layer services setup, like
  [stock]  /usr/share/runit/sv/  --> original copy managed by dpkg
  [local]  /etc/sv/              --> local modified copy, if any
  [live]   /run/runit/sv/        --> copy supervised by runsv
  where /etc/sv can be empty, and [live] is populated with copies of
  services from [local] if any, from [stock] otherwise.

the above allow me (maintainer) to upgrade the [live] copy for service
foo with [stock] unless [local] foo exists; much simpler than when
the service in under /etc/sv
It also separates service directories supervised by runsv and services
directories managed by dpkg (necessary to fix both A and B).

Also to address B /run/runit/sv can be a symlink to a timestamped
/run/runit/sv.time dir that contains copies of services dirs; each
upgrade adds a new sv.time dir  and switches the symlink to the
new sv.time(you can roll back a service dir upgrade, there will be
multiple sv.time under /run/runit and so on); again it avoid the added
complexity of conffiles ( and a pile of sv.time dirs that accumulates
under /etc/)

--------------------------------------------------------------------

right now I'm taking some time to think about this: nobody complained
so far about A or B [1], no runit user requested any of the above
features; there is added complexity with this setup and it requires a
relevant effort on my side. Also,some people will likely be unhappy
about this. Overall I'm tempted to just sit and wait until someone
complains and spend my time to solve other runit issues meanwhile.

[1] I think a large number of users and dpkg-provide services are
needed to trigger A or B; none of the two is true right now in Debian

Reply via email to