Dealing with read-only rootfs

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



On So, 17.06.18 18:58, Jérémy Rosen (jeremy.rosen at smile.fr) wrote:

> Hello everybody
> 
> I am trying to understand the recommanded way to deal with read-only
> rootfs...

Have you seen this btw:

http://0pointer.net/blog/projects/stateless.html

It's from 2014, and a number of things happened since them, but it
introduces the basic concepts.

> my understanding is that (slightly simplified)
> * /run must be a tmpfs

Well, this is the case for all systems, not just those with read-only
root. systemd will mounte /run as tmpfs for you anyway and in any
case, it's not something you ever have to think about. It's basically
in the same category as /sys and /dev: it's mounted implicitly and not
up to distributors or even users to change. Or to say this
differently: if you want to use something else than tmpfs on /run then
you are welcome, but you are on your own, and systemd won't make that
easy for you.

> * /var must be writable, and will usually be persistant (can be a
>   tmpfs too)

Correct. Also see file-hierarchy(7).

> * everything else can be read-only

Yes, in particular /etc and /usr can be read-only.

> My problem comes with populating an empty /var. There seems to be hints to a
> systemd-provided mechanism to do that, but I can't find any documentation
> for it

systemd will set everything up as needed automatically for you, and
well-behaved packages do that too. There are generally three options
to make sure that a package has everything it needs under /var:

1. Add tmpfiles.d/ snippets to create the dirs that are needed if they
   are missing. systemd ships some basic ones, that set up the basic
   hierarchy, and everything it needs for its own components. But 3rd
   party package can install whatever they want on top. Note that
   tmpfiles.d/ knows the "C" line which copies whole directory trees
   into /var if that is needed. It defaults to copying those from
   /usr/share/factory, but you actually can copy them from anywhere
   you like. Usually using "C" for /var is not really necessary
   though, as most software is happy with just a few properly owned
   dirs bein created for them, and doesn#t need any copied fields. "C"
   is very handy however if you also start with an empty /etc, because
   it can then be used to do some minimal population of /etc, which is
   necessary for more software to work correctly.

2. Add StateDirectory=, CacheDirectory=, LogsDirectory= to your
   service file. Many services only need a directory or two underneath
   /var/lib/, /var/cache/ and /var/log/, and if that's the case it's
   much nicer to use these three settings to embedd this info directly
   in the unit file.

3. Fix the service in question to create evertyhing it needs
   implicitly on first run. This of course is the most robust
   solution, but there are limits to this, for example if the service
   never possesses privileges.

> Apparently, tmpfiles.d should copy the content from /usr/share/factory to
> /var when /var is empty, but I can't find what actually implements that
> 
> * is it dynamically added in /run ?
> * is it just a recommanded way, and I have to implemented myself ? if yes,
> is the directory /usr/share/factory documented anywhere ?

Yes, in both file-hierarchy(7) and tmpfiles.d(5).

> * what qualifies as "empty /var" ? (this is mostly about being robust to
> power-loss during the copying of /var)

tmpfiles snippets run on every boot and adjust what is necessary but
are happy to use what is already there. This means that they can
safely run on every boot, and will continue where a previous run left
of if necessary.

Lennart

-- 
Lennart Poettering, Red Hat


[Index of Archives]     [LARTC]     [Bugtraq]     [Yosemite Forum]     [Photo]

  Powered by Linux