system: add option to handle /var as an overlayfs with r/o rootfs (branch yem/systemdify-var)
v4 cover system: add option to handle /var as an overlayfs with r/o rootfs (branch yem/systemdify-var)
Hello All!
This three-patch series introduces an alternate option to handle /var as an overlayfs, when using a read-only rootfs with systemd.
The rationale behind wanting to use an overlayfs rather than the factory we used to create so far, is that in some corner-cases, the factory does not work, and can't easily be fixed (mesmerising hand-waving...), while the overlayfs Just-Works™ (at the expense of a little trickery at runtime).
This series would not have been entirely possible without the input from Norbert, who provided the basis for the overlayfs-based solution, and explanations on how things fit together in a systemd system. Thanks!
Changes v3 -> v4:
- drop patches already applied
- split mounting the base tmpfs out of the service unit and into its own .mount unit
- rename the service unit to a more appropriate name
- update explanations on hos to provide one's own backing store instead of the tmpfs
Changes v2 -> v3:
- introduce the overlayfs-based proposal from Norbert
- some rewording
- some typo fixes (yah, Yann being Yann being me...)
Changes v1 -> v2:
- split Yann@work initial patch into the first two patch
- move the systemd-tmpfile handling to the skeleton
- introduce options to enable/disable factory or systemd-tmpfiles
Regards,
Yann E. MORIN.
----------------------------------------------------------------
Yann E. MORIN (3):
system: introduce a choice for /var management
system: add option to use an overlayfs on /var on a r/o root w/ systemd support/testing: add systemd tests for factory and overlayfs
.../skeleton-init-systemd/{ => factory}/var.mount | 0
.../overlayfs/prepare-var-overlay.service | 19 ++
.../overlayfs/run-buildroot-mounts-var.mount | 12 ++
package/skeleton-init-systemd/overlayfs/var.mount | 14 ++
.../skeleton-init-systemd/skeleton-init-systemd.mk | 28 ++-
.../testing/conf/overlayfs-kernel-fragment.config | 1 +
.../run-buildroot-mounts-var.mount.d/base.conf | 2 +
support/testing/tests/init/test_systemd.py | 209 ++++++++++++++++++++-
system/Config.in | 48 ++++-
9 files changed, 311 insertions(+), 22 deletions(-)
rename package/skeleton-init-systemd/{ => factory}/var.mount (100%)
create mode 100644 package/skeleton-init-systemd/overlayfs/prepare-var-overlay.service
create mode 100644 package/skeleton-init-systemd/overlayfs/run-buildroot-mounts-var.mount
create mode 100644 package/skeleton-init-systemd/overlayfs/var.mount
create mode 100644 support/testing/conf/overlayfs-kernel-fragment.config
create mode 100644 support/testing/tests/init/systemd-overlay/usr/lib/systemd/system/run-buildroot-mounts-var.mount.d/base.confSignature · 10 lines
.-----------------.--------------------.------------------.--------------------. | Yann E. MORIN | Real-Time Embedded | /"\ ASCII RIBBON | Erics' conspiracy: | | +33 662 376 056 | Software Designer | \ / CAMPAIGN | ___ | | +33 561 099 427 `------------.-------: X AGAINST | \e/ There is no | | http://ymorin.is-a-geek.org/ | _/*\_ | / \ HTML MAIL | v conspiracy. | '------------------------------^-------^------------------^--------------------' _______________________________________________ buildroot mailing list [email protected] https://lists.buildroot.org/mailman/listinfo/buildroot
PATCH v4 1/3 system: introduce a choice for /var management
From: "Yann E. MORIN" <[email protected]>
Currently, we have a single solution to handle the /var content on a read-only root filesystem, and users can opt out of using it.
We're going to introduce another solution (based on an overlayfs), which is incompatible with using the factory, so we'll have a choice of three mutually exclusive options.
Introduce that choice now with just the existing /var factory, and a new option to opt out of it.
--- system/Config.in | 22 +++++++++++++++++++--- 1 file changed, 19 insertions(+), 3 deletions(-)
system/Config.in +19 -3
@@ -156,10 +156,16 @@ endchoice if BR2_INIT_SYSTEMD -config BR2_INIT_SYSTEMD_VAR_FACTORY - bool "build a factory to populate a tmpfs on /var" - default y # legacy +choice + bool "/var management" + default BR2_INIT_SYSTEMD_VAR_FACTORY # legacy depends on !BR2_TARGET_GENERIC_REMOUNT_ROOTFS_RW + help + Select how Buildroot provides a read-write /var when the + rootfs is not remounted read-write. + +config BR2_INIT_SYSTEMD_VAR_FACTORY + bool "build a factory to populate a tmpfs" help Build a factory of the content of /var as installed by packages, mount a tmpfs on /var at runtime, so that
@@ -181,6 +187,16 @@ config BR2_INIT_SYSTEMD_VAR_FACTORY var.mount unit, that overrides the What and Type, and possibly the Options and After, fields. +config BR2_INIT_SYSTEMD_VAR_NONE + bool "do nothing" + help + Choose this if you have custom dispositions (like one or more + of a post-build script, a fakeroot script, systemd units, an + initramfs, or something else) that prepare /var to be writable + on a read-only rootfs. + +endchoice + config BR2_INIT_SYSTEMD_POPULATE_TMPFILES bool "trigger systemd-tmpfiles during build" default y # legacy
Signature · 6 lines
2.25.1 _______________________________________________ buildroot mailing list [email protected] https://lists.buildroot.org/mailman/listinfo/buildroot
Re: [Buildroot] [PATCH 1/3 v4] system: introduce a choice for /var management
Am So., 25. Dez. 2022 um 23:08 Uhr schrieb Yann E. MORIN <[email protected]>:
Quoted 13 lines
From: "Yann E. MORIN" <[email protected]>
Currently, we have a single solution to handle the /var content on a read-only root filesystem, and users can opt out of using it.
We're going to introduce another solution (based on an overlayfs), which is incompatible with using the factory, so we'll have a choice of three mutually exclusive options.
Introduce that choice now with just the existing /var factory, and a new option to opt out of it.
Quoted 7 lines
Signed-off-by Yann E. MORIN <[email protected]>Signed-off-by Yann E. MORIN <[email protected]>Cc Norbert Lange <[email protected]>Cc Arnout Vandecappelle (Essensium/Mind) <[email protected]>Cc Romain Naour <[email protected]>Cc Jérémy Rosen <[email protected]>Acked-by Norbert Lange <[email protected]>
Hello Yann,
I know I already acked this, but...
Quoted 9 lines
--- system/Config.in | 22 +++++++++++++++++++--- 1 file changed, 19 insertions(+), 3 deletions(-)system/Config.in +0
-0
system/Config.in endchoice · line 162
Quoted 10 lines
system/Config.in +3
-3@@ -156,10 +156,16 @@ endchoice if BR2_INIT_SYSTEMD -config BR2_INIT_SYSTEMD_VAR_FACTORY - bool "build a factory to populate a tmpfs on /var" - default y # legacy +choice + bool "/var management" + default BR2_INIT_SYSTEMD_VAR_FACTORY # legacy depends on !BR2_TARGET_GENERIC_REMOUNT_ROOTFS_RW
Consider that the option is used to *remount* the filesystem, but you could mount the filesystem read-write, in which case you probably *dont want* some specific var handling.
So maybe:
drop 'depends on !BR2_TARGET_GENERIC_REMOUNT_ROOTFS_RW'
if !BR2_TARGET_GENERIC_REMOUNT_ROOTFS_RW
make the default BR2_INIT_SYSTEMD_VAR_FACTORY
otherwise
make the default BR2_INIT_SYSTEMD_VAR_NONE
I believe the choice should be always there.
Quoted 27 lines
system/Config.in +16
-1+ help + Select how Buildroot provides a read-write /var when the + rootfs is not remounted read-write. + +config BR2_INIT_SYSTEMD_VAR_FACTORY + bool "build a factory to populate a tmpfs" help Build a factory of the content of /var as installed by packages, mount a tmpfs on /var at runtime, so that@@ -181,6 +187,16 @@ config BR2_INIT_SYSTEMD_VAR_FACTORY var.mount unit, that overrides the What and Type, and possibly the Options and After, fields. +config BR2_INIT_SYSTEMD_VAR_NONE + bool "do nothing" + help + Choose this if you have custom dispositions (like one or more + of a post-build script, a fakeroot script, systemd units, an + initramfs, or something else) that prepare /var to be writable + on a read-only rootfs. + +endchoice + config BR2_INIT_SYSTEMD_POPULATE_TMPFILES bool "trigger systemd-tmpfiles during build" default y # legacy --
Quoted 2 lines
2.25.1
Norbert
_______________________________________________
buildroot mailing list
[email protected]
https://lists.buildroot.org/mailman/listinfo/buildroot
Re: [Buildroot] [PATCH 1/3 v4] system: introduce a choice for /var management
Norbert, All,
On 2023-01-09 00:22 +0100, Norbert Lange spake thusly:
Quoted 22 lines
Am So., 25. Dez. 2022 um 23:08 Uhr schrieb Yann E. MORIN <[email protected]>:
Quoted 12 lines
From: "Yann E. MORIN" <[email protected]>
Currently, we have a single solution to handle the /var content on a read-only root filesystem, and users can opt out of using it.
We're going to introduce another solution (based on an overlayfs), which is incompatible with using the factory, so we'll have a choice of three mutually exclusive options.
Introduce that choice now with just the existing /var factory, and a new option to opt out of it.
Quoted 7 lines
Signed-off-by Yann E. MORIN <[email protected]>Signed-off-by Yann E. MORIN <[email protected]>Cc Norbert Lange <[email protected]>Cc Arnout Vandecappelle (Essensium/Mind) <[email protected]>Cc Romain Naour <[email protected]>Cc Jérémy Rosen <[email protected]>Acked-by Norbert Lange <[email protected]>
Quoted 3 lines
Hello Yann,
I know I already acked this, but...
As long as the patch has not been applied, it is never too late to provide feedback. :-)
Quoted 12 lines
Quoted 12 lines
--- system/Config.in | 22 +++++++++++++++++++--- 1 file changed, 19 insertions(+), 3 deletions(-)system/Config.in +0
-0@@ -156,10 +156,16 @@ endchoice if BR2_INIT_SYSTEMD
Quoted 11 lines
system/Config.in endchoice · line 162
Quoted 7 lines
system/Config.in +3
-3-config BR2_INIT_SYSTEMD_VAR_FACTORY - bool "build a factory to populate a tmpfs on /var" - default y # legacy +choice + bool "/var management" + default BR2_INIT_SYSTEMD_VAR_FACTORY # legacy depends on !BR2_TARGET_GENERIC_REMOUNT_ROOTFS_RWConsider that the option is used to *remount* the filesystem, but you could mount the filesystem read-write, in which case you probably *dont want* some specific var handling.
Sorry, I am not sure I followed you there. Did you mean "passing 'rw' on the kernel command line", "directly mounting r/w from an initrd", or something along those lines?
Quoted 10 lines
So maybe:
drop 'depends on !BR2_TARGET_GENERIC_REMOUNT_ROOTFS_RW'
if !BR2_TARGET_GENERIC_REMOUNT_ROOTFS_RW
make the defaultBR2_INIT_SYSTEMD_VAR_FACTORY
otherwise
make the defaultBR2_INIT_SYSTEMD_VAR_NONEI believe the choice should be always there.
This change is meant so that the behaviour by default does not change. Previously, our /var factory was always created when, and only created when, BR2_TARGET_GENERIC_REMOUNT_ROOTFS_RW was not set.
So, this new choice reflects that. Since the only option apart from the /var factory, is to do nothing, there is no point in exposing the choice altogether.
If we want to always expose the choice, then I believe this should be done in a different patch. At which point we could do as you suggest.
Note that I am not too fond of BR2_TARGET_GENERIC_REMOUNT_ROOTFS_RW to begin with, because its semantics are not very strong.
First, it is possible to select it, even though the rootfs will be by design read-only (e.g. squashfs), so it does not make sense to set BR2_TARGET_GENERIC_REMOUNT_ROOTFS_RW=y in that case.
Second, as you mentioned above, it is also possible that the rootfs is rw, either because of the kernel command line, or because of an initrd that arranged for it to be rw (e.g. by actually mounting rw a rw-capable fs, or by mounting a rw-capable overlayfs over an otherwise ro filesystem), all without setting BR2_TARGET_GENERIC_REMOUNT_ROOTFS_RW=y.
So, ultimately, I agree that we should stop using BR2_TARGET_GENERIC_REMOUNT_ROOTFS_RW to discriminate between running on a rw or ro rootfs, but so far that's the best we have... And again, it keeps the default the same as previously.
Regards,
Yann E. MORIN.
Quoted 31 lines
Quoted 27 lines
system/Config.in +16
-1+ help + Select how Buildroot provides a read-write /var when the + rootfs is not remounted read-write. + +config BR2_INIT_SYSTEMD_VAR_FACTORY + bool "build a factory to populate a tmpfs" help Build a factory of the content of /var as installed by packages, mount a tmpfs on /var at runtime, so that@@ -181,6 +187,16 @@ config BR2_INIT_SYSTEMD_VAR_FACTORY var.mount unit, that overrides the What and Type, and possibly the Options and After, fields. +config BR2_INIT_SYSTEMD_VAR_NONE + bool "do nothing" + help + Choose this if you have custom dispositions (like one or more + of a post-build script, a fakeroot script, systemd units, an + initramfs, or something else) that prepare /var to be writable + on a read-only rootfs. + +endchoice + config BR2_INIT_SYSTEMD_POPULATE_TMPFILES bool "trigger systemd-tmpfiles during build" default y # legacy --Quoted 2 lines
2.25.1
Norbert
Signature · 26 lines
____________ .-----------------.--------------------: _ :------------------. | Yann E. MORIN | Real-Time Embedded | __/ ) | /"\ ASCII RIBBON | | | Software Designer | _/ - /' | \ / CAMPAIGN | | +33 638.411.245 '--------------------: (_ `--, | X AGAINST | | yann.morin (at) orange.com |_=" ,--' | / \ HTML MAIL | '--------------------------------------:______/_____:------------------' _________________________________________________________________________________________________________________________ Ce message et ses pieces jointes peuvent contenir des informations confidentielles ou privilegiees et ne doivent donc pas etre diffuses, exploites ou copies sans autorisation. Si vous avez recu ce message par erreur, veuillez le signaler a l'expediteur et le detruire ainsi que les pieces jointes. Les messages electroniques etant susceptibles d'alteration, Orange decline toute responsabilite si ce message a ete altere, deforme ou falsifie. Merci. This message and its attachments may contain confidential or privileged information that may be protected by law; they should not be distributed, used or copied without authorisation. If you have received this email in error, please notify the sender and delete this message and its attachments. As emails may be altered, Orange is not liable for messages that have been modified, changed or falsified. Thank you. _______________________________________________ buildroot mailing list [email protected] https://lists.buildroot.org/mailman/listinfo/buildroot
Re: [Buildroot] [PATCH 1/3 v4] system: introduce a choice for /var management
Am Di., 10. Jan. 2023 um 09:24 Uhr schrieb <[email protected]>:
Quoted 57 lines
Norbert, All,
On 2023-01-09 00:22 +0100, Norbert Lange spake thusly:
Quoted 22 lines
Am So., 25. Dez. 2022 um 23:08 Uhr schrieb Yann E. MORIN <[email protected]>:
Quoted 12 lines
From: "Yann E. MORIN" <[email protected]>
Currently, we have a single solution to handle the /var content on a read-only root filesystem, and users can opt out of using it.
We're going to introduce another solution (based on an overlayfs), which is incompatible with using the factory, so we'll have a choice of three mutually exclusive options.
Introduce that choice now with just the existing /var factory, and a new option to opt out of it.
Quoted 7 lines
Signed-off-by Yann E. MORIN <[email protected]>Signed-off-by Yann E. MORIN <[email protected]>Cc Norbert Lange <[email protected]>Cc Arnout Vandecappelle (Essensium/Mind) <[email protected]>Cc Romain Naour <[email protected]>Cc Jérémy Rosen <[email protected]>Acked-by Norbert Lange <[email protected]>Quoted 3 lines
Hello Yann,
I know I already acked this, but...
As long as the patch has not been applied, it is never too late to provide feedback. :-)
Quoted 12 lines
Quoted 12 lines
--- system/Config.in | 22 +++++++++++++++++++--- 1 file changed, 19 insertions(+), 3 deletions(-)system/Config.in +0
-0@@ -156,10 +156,16 @@ endchoice if BR2_INIT_SYSTEMDQuoted 11 lines
system/Config.in endchoice · line 162
Quoted 7 lines
system/Config.in +3
-3-config BR2_INIT_SYSTEMD_VAR_FACTORY - bool "build a factory to populate a tmpfs on /var" - default y # legacy +choice + bool "/var management" + default BR2_INIT_SYSTEMD_VAR_FACTORY # legacy depends on !BR2_TARGET_GENERIC_REMOUNT_ROOTFS_RWConsider that the option is used to *remount* the filesystem, but you could mount the filesystem read-write, in which case you probably *dont want* some specific var handling.
Quoted 3 lines
Sorry, I am not sure I followed you there. Did you mean "passing 'rw' on the kernel command line", "directly mounting r/w from an initrd", or something along those lines?
Yes, basically no remount necessary, the option seems to assume that the rootfs is always mounted ro before systemd takes over, which might not be the case for multiple reasons.
Quoted 16 lines
Quoted 11 lines
So maybe:
drop 'depends on !BR2_TARGET_GENERIC_REMOUNT_ROOTFS_RW'
if !BR2_TARGET_GENERIC_REMOUNT_ROOTFS_RW
make the defaultBR2_INIT_SYSTEMD_VAR_FACTORY
otherwise
make the defaultBR2_INIT_SYSTEMD_VAR_NONEI believe the choice should be always there.
This change is meant so that the behaviour by default does not change. Previously, our /var factory was always created when, and only created when,
BR2_TARGET_GENERIC_REMOUNT_ROOTFS_RWwas not set.
Quoted 6 lines
So, this new choice reflects that. Since the only option apart from the /var factory, is to do nothing, there is no point in exposing the choice altogether.
If we want to always expose the choice, then I believe this should be done in a different patch. At which point we could do as you suggest.
Ok, though I dont understand the reasoning for the split.
With or without those modifications (submenu always available or conditional), the behavior is the same as before *for existing configs*?
Quoted 13 lines
Note that I am not too fond of
BR2_TARGET_GENERIC_REMOUNT_ROOTFS_RWto begin with, because its semantics are not very strong.First, it is possible to select it, even though the rootfs will be by design read-only (e.g. squashfs), so it does not make sense to set BR2_TARGET_GENERIC_REMOUNT_ROOTFS_RW=y in that case.
Second, as you mentioned above, it is also possible that the rootfs is rw, either because of the kernel command line, or because of an initrd that arranged for it to be rw (e.g. by actually mounting rw a rw-capable fs, or by mounting a rw-capable overlayfs over an otherwise ro filesystem), all without setting BR2_TARGET_GENERIC_REMOUNT_ROOTFS_RW=y.
Quoted 4 lines
So, ultimately, I agree that we should stop using
BR2_TARGET_GENERIC_REMOUNT_ROOTFS_RWto discriminate between running on a rw or ro rootfs, but so far that's the best we have... And again, it keeps the default the same as previously.
Well, if you plan on changing it later, wouldn't it be better to not depend on it,
but always have the specific BR2_INIT_SYSTEMD_VAR_* in your config?
Regards, Norbert
_______________________________________________
buildroot mailing list
[email protected]
https://lists.buildroot.org/mailman/listinfo/buildroot
PATCH v4 2/3 system: add option to use an overlayfs on /var on a r/o root w/ systemd
In reply to Yann E. MORINFrom: "Yann E. MORIN" <[email protected]>
While the /var factory seems to be working in most cases, there have been suggestions that it may be slightly and subtely borken in some (rare? edge?) cases, especially about symlinks.
An other solution is to pre-populate /var at build time, by way of calling systemd-tmpfiles, and mounting an overlayfs on-top of it at runtime. The first part is already done, and this change focuses on mountig the overlayfs.
This is slightly accrobatic, though, and requires a few hoops:
- first, we create a tmpfs; this will server as the backing store for
the writable part of the overlayfs;
- there, we create three directories for the overlayfs:
- lower/, upper/, and work/, to serve as the respective overlayfs directories,
- note: the 'upper' and 'work' have to be on the same filesystem;
- then we bind-mount /var onto lower/
- eventually we mount the overlayfs
We are doing that with three systemd units, with the latter having a dependency on the previous one:
- the tmpfs is created as a standalone mount unit, first because that just makes sense to use systemd to do the mount, and second because that will make it easy gfor users to provide an actual backing store for /var, by just providing a dropin that overrides the What with the desitred backing store, and optionally adding dependencies on other services to create/initialise the backing store if needed.
- creating the directories is done with their own service file, as there is no other easy way to reate them automatically. We also bind-mount /var onto the lower in that service file, instead of using a systemd mount unit. See [0] for the rationale.
- finally, we mount an overlay on /var with a classic systemd mount unit.
[0] if we had a systemd mount unit to do the bind mount, then it sould look like:
# run-buildroot-mounts-var-lower.mount
[Mount]
What=/var
Where=/run/buildroot/mounts/var/lower
Options=bindand then the var.mount unit would need to have a dependency on that unit:
# var.mount
[Unit]
After=run-buildroot-mounts-var-lower.mount
[Mount]
Where=/varHowever, the What=/var of the first unit automatically adds an implicit dependency on /var, and since there is a unit providing Where=/var, we would have run-buildroot-mounts-var-lower.mount depend on var.mount, but we need var.mount to depend on run-buildroot-mounts-var-lower.mount, so this is a circular dependency. There is no way to tell systemd no to add the implicit dependency. So we do the bind mont manually in the service unit that prepares the overlay structure.
Norbert provided some systemd units as a starting point, and that was quite a huge help in understanding how to fit all those things together.
---
.../{ => factory}/var.mount | 0
.../overlayfs/prepare-var-overlay.service | 19 +++++++++++++
.../overlayfs/run-buildroot-mounts-var.mount | 12 ++++++++
.../skeleton-init-systemd/overlayfs/var.mount | 14 ++++++++++
.../skeleton-init-systemd.mk | 28 +++++++++++++++++--
system/Config.in | 26 ++++++++++++-----
6 files changed, 89 insertions(+), 10 deletions(-)
rename package/skeleton-init-systemd/{ => factory}/var.mount (100%)
create mode 100644 package/skeleton-init-systemd/overlayfs/prepare-var-overlay.service
create mode 100644 package/skeleton-init-systemd/overlayfs/run-buildroot-mounts-var.mount
create mode 100644 package/skeleton-init-systemd/overlayfs/var.mountpackage/skeleton-init-systemd/factory/var.mount renamed from package/skeleton-init-systemd/var.mount +0 -0
package/skeleton-init-systemd/overlayfs/prepare-var-overlay.service new file +19 -0
@@ -0,0 +1,19 @@ +[Unit] +Description=Variable storage overlay setup +ConditionPathIsSymbolicLink=!/var +DefaultDependencies=no +RequiresMountsFor=/run/buildroot/mounts/var + +[Service] +Type=oneshot +RemainAfterExit=yes +ExecStart=/usr/bin/mkdir -p /run/buildroot/mounts/var/lower /run/buildroot/mounts/var/upper /run/buildroot/mounts/var/work + +# Ideally, we would like to use a systemd mount unit to manage the bind +# mount. Unfortunately, that creates a circular dependency: such a unit +# would have What=/var while var.mount has Where=/var so that introduces +# an implicit dependency from that unit to var.mount, but var.mount +# would have an explicit dependency to be ordered after that unit. +# So we handle the bind mount manually. +ExecStart=/usr/bin/mount -n -o bind,private /var /run/buildroot/mounts/var/lower +ExecStop=/usr/bin/umount -l /run/buildroot/mounts/var/lower
package/skeleton-init-systemd/overlayfs/run-buildroot-mounts-var.mount new file +12 -0
@@ -0,0 +1,12 @@ +[Unit] +Description=Variable storage overlay tmpfs +ConditionPathIsSymbolicLink=!/var +DefaultDependencies=no +After=local-fs-pre.target + +[Mount] +What=var_overlay_tmpfs +Where=/run/buildroot/mounts/var +Type=tmpfs +Options=private +LazyUnmount=true
package/skeleton-init-systemd/overlayfs/var.mount new file +14 -0
@@ -0,0 +1,14 @@ +[Unit] +Description=Variable storage overlay +Documentation=man:file-hierarchy(7) +ConditionPathIsSymbolicLink=!/var +DefaultDependencies=no +After=prepare-var-overlay.service +BindsTo=prepare-var-overlay.service + +[Mount] +What=overlay_var +Where=/var +Type=overlay +Options=lowerdir=/run/buildroot/mounts/var/lower,upperdir=/run/buildroot/mounts/var/upper,workdir=/run/buildroot/mounts/var/work,redirect_dir=on,index=on,xino=on +LazyUnmount=true
package/skeleton-init-systemd/skeleton-init-systemd.mk +25 -3
@@ -33,7 +33,7 @@ endef # a real (but empty) directory, and the "factory files" will be copied # back there by the tmpfiles.d mechanism. ifeq ($(BR2_INIT_SYSTEMD_VAR_FACTORY),y) -define SKELETON_INIT_SYSTEMD_PRE_ROOTFS_VAR +define SKELETON_INIT_SYSTEMD_PRE_ROOTFS_VAR_FACTORY rm -rf $(TARGET_DIR)/usr/share/factory/var mv $(TARGET_DIR)/var $(TARGET_DIR)/usr/share/factory/var mkdir -p $(TARGET_DIR)/var
@@ -52,11 +52,33 @@ define SKELETON_INIT_SYSTEMD_PRE_ROOTFS_VAR || exit 1; \ fi; \ done >$(TARGET_DIR)/usr/lib/tmpfiles.d/00-buildroot-var.conf - $(INSTALL) -D -m 0644 $(SKELETON_INIT_SYSTEMD_PKGDIR)/var.mount \ + $(INSTALL) -D -m 0644 $(SKELETON_INIT_SYSTEMD_PKGDIR)/factory/var.mount \ $(TARGET_DIR)/usr/lib/systemd/system/var.mount endef -SKELETON_INIT_SYSTEMD_ROOTFS_PRE_CMD_HOOKS += SKELETON_INIT_SYSTEMD_PRE_ROOTFS_VAR +SKELETON_INIT_SYSTEMD_ROOTFS_PRE_CMD_HOOKS += SKELETON_INIT_SYSTEMD_PRE_ROOTFS_VAR_FACTORY endif # BR2_INIT_SYSTEMD_VAR_FACTORY + +ifeq ($(BR2_INIT_SYSTEMD_VAR_OVERLAYFS),y) + +define SKELETON_INIT_SYSTEMD_LINUX_CONFIG_FIXUPS + $(call KCONFIG_ENABLE_OPT,CONFIG_OVERLAY_FS) +endef + +define SKELETON_INIT_SYSTEMD_PRE_ROOTFS_VAR_OVERLAYFS + $(INSTALL) -D -m 0644 \ + $(SKELETON_INIT_SYSTEMD_PKGDIR)/overlayfs/run-buildroot-mounts-var.mount \ + $(TARGET_DIR)/usr/lib/systemd/system/run-buildroot-mounts-var.mount + $(INSTALL) -D -m 0644 \ + $(SKELETON_INIT_SYSTEMD_PKGDIR)/overlayfs/prepare-var-overlay.service \ + $(TARGET_DIR)/usr/lib/systemd/system/prepare-var-overlay.service + $(INSTALL) -D -m 0644 \ + $(SKELETON_INIT_SYSTEMD_PKGDIR)/overlayfs/var.mount \ + $(TARGET_DIR)/usr/lib/systemd/system/var.mount +endef +SKELETON_INIT_SYSTEMD_POST_INSTALL_TARGET_HOOKS += SKELETON_INIT_SYSTEMD_PRE_ROOTFS_VAR_OVERLAYFS + +endif # BR2_INIT_SYSTEMD_VAR_OVERLAYFS + endif # BR2_TARGET_GENERIC_REMOUNT_ROOTFS_RW ifeq ($(BR2_INIT_SYSTEMD_POPULATE_TMPFILES),y)
system/Config.in +19 -7
@@ -164,6 +164,14 @@ choice Select how Buildroot provides a read-write /var when the rootfs is not remounted read-write. + Note: Buildroot uses a tmpfs, either as a mount point or as + the upper of an overlayfs, so as to at least make the system + bootable out of the box; mounting a filesystem from actual + storage is left to the integration, as it is too specific and + may need preparatory work like partitionning a device and/or + formatting a filesystem first, which falls out of the scope + of Buildroot. + config BR2_INIT_SYSTEMD_VAR_FACTORY bool "build a factory to populate a tmpfs" help
@@ -176,17 +184,21 @@ config BR2_INIT_SYSTEMD_VAR_FACTORY It probably does not play very well with triggering a call to systemd-tmpfiles at build time (below). - Note: Buildroot mounts a tmpfs on /var to at least make the - system bootable out of the box; mounting a filesystem from - actual storage is left to the integration, as it is too - specific and may need preparatory work like partitionning a - device and/or formatting a filesystem first, so that falls - out of the scope of Buildroot. - To use persistent storage, provide a systemd dropin for the var.mount unit, that overrides the What and Type, and possibly the Options and After, fields. +config BR2_INIT_SYSTEMD_VAR_OVERLAYFS + bool "mount an overlayfs backed by a tmpfs" + select BR2_INIT_SYSTEMD_POPULATE_TMPFILES + help + Mount an overlayfs on /var, with the upper as a tmpfs. + + To use a persistent storage, provide a systemd dropin for the + run-buildroot-mounts-var.mount unit, that overrides the What + and Type, and possibly Options, fields, and adds necessary + dependencies on other services. + config BR2_INIT_SYSTEMD_VAR_NONE bool "do nothing" help
Signature · 6 lines
2.25.1 _______________________________________________ buildroot mailing list [email protected] https://lists.buildroot.org/mailman/listinfo/buildroot
Re: [Buildroot] [PATCH 2/3 v4] system: add option to use an overlayfs on /var on a r/o root w/ systemd
Am So., 25. Dez. 2022 um 23:08 Uhr schrieb Yann E. MORIN <[email protected]>:
Quoted 255 lines
From: "Yann E. MORIN" <[email protected]>
While the /var factory seems to be working in most cases, there have been suggestions that it may be slightly and subtely borken in some (rare? edge?) cases, especially about symlinks.
An other solution is to pre-populate /var at build time, by way of calling systemd-tmpfiles, and mounting an overlayfs on-top of it at runtime. The first part is already done, and this change focuses on mountig the overlayfs.
This is slightly accrobatic, though, and requires a few hoops:
- first, we create a tmpfs; this will server as the backing store for
the writable part of the overlayfs;- there, we create three directories for the overlayfs:
- lower/, upper/, and work/, to serve as the respective overlayfs directories,
- note: the 'upper' and 'work' have to be on the same filesystem;- then we bind-mount /var onto lower/
- eventually we mount the overlayfs
We are doing that with three systemd units, with the latter having a dependency on the previous one:
- the tmpfs is created as a standalone mount unit, first because that just makes sense to use systemd to do the mount, and second because that will make it easy gfor users to provide an actual backing store for /var, by just providing a dropin that overrides the What with the desitred backing store, and optionally adding dependencies on other services to create/initialise the backing store if needed.
- creating the directories is done with their own service file, as there is no other easy way to reate them automatically. We also bind-mount /var onto the lower in that service file, instead of using a systemd mount unit. See [0] for the rationale.
- finally, we mount an overlay on /var with a classic systemd mount unit.
[0] if we had a systemd mount unit to do the bind mount, then it sould look like:
# run-buildroot-mounts-var-lower.mount [Mount] What=/var Where=/run/buildroot/mounts/var/lower Options=bindand then the var.mount unit would need to have a dependency on that unit:
# var.mount [Unit] After=run-buildroot-mounts-var-lower.mount [Mount] Where=/varHowever, the What=/var of the first unit automatically adds an implicit dependency on /var, and since there is a unit providing Where=/var, we would have run-buildroot-mounts-var-lower.mount depend on var.mount, but we need var.mount to depend on run-buildroot-mounts-var-lower.mount, so this is a circular dependency. There is no way to tell systemd no to add the implicit dependency. So we do the bind mont manually in the service unit that prepares the overlay structure.
Norbert provided some systemd units as a starting point, and that was quite a huge help in understanding how to fit all those things together.
Co-authored-by Norbert Lange <[email protected]>Signed-off-by Yann E. MORIN <[email protected]>Cc Norbert Lange <[email protected]>Cc Romain Naour <[email protected]>Cc Jérémy Rosen <[email protected]>Signed-off-by Yann E. MORIN <[email protected]>--- .../{ => factory}/var.mount | 0 .../overlayfs/prepare-var-overlay.service | 19 +++++++++++++ .../overlayfs/run-buildroot-mounts-var.mount | 12 ++++++++ .../skeleton-init-systemd/overlayfs/var.mount | 14 ++++++++++ .../skeleton-init-systemd.mk | 28 +++++++++++++++++-- system/Config.in | 26 ++++++++++++----- 6 files changed, 89 insertions(+), 10 deletions(-) rename package/skeleton-init-systemd/{ => factory}/var.mount (100%) create mode 100644 package/skeleton-init-systemd/overlayfs/prepare-var-overlay.service create mode 100644 package/skeleton-init-systemd/overlayfs/run-buildroot-mounts-var.mount create mode 100644 package/skeleton-init-systemd/overlayfs/var.mountpackage/skeleton-init-systemd/factory/var.mount renamed from package/skeleton-init-systemd/var.mount +0
-0package/skeleton-init-systemd/overlayfs/prepare-var-overlay.service new file +19
-0@@ -0,0 +1,19 @@ +[Unit] +Description=Variable storage overlay setup +ConditionPathIsSymbolicLink=!/var +DefaultDependencies=no +RequiresMountsFor=/run/buildroot/mounts/var + +[Service] +Type=oneshot +RemainAfterExit=yes +ExecStart=/usr/bin/mkdir -p /run/buildroot/mounts/var/lower /run/buildroot/mounts/var/upper /run/buildroot/mounts/var/work + +# Ideally, we would like to use a systemd mount unit to manage the bind +# mount. Unfortunately, that creates a circular dependency: such a unit +# would have What=/var while var.mount has Where=/var so that introduces +# an implicit dependency from that unit to var.mount, but var.mount +# would have an explicit dependency to be ordered after that unit. +# So we handle the bind mount manually. +ExecStart=/usr/bin/mount -n -o bind,private /var /run/buildroot/mounts/var/lower +ExecStop=/usr/bin/umount -l /run/buildroot/mounts/var/lowerpackage/skeleton-init-systemd/overlayfs/run-buildroot-mounts-var.mount new file +12
-0@@ -0,0 +1,12 @@ +[Unit] +Description=Variable storage overlay tmpfs +ConditionPathIsSymbolicLink=!/var +DefaultDependencies=no +After=local-fs-pre.target + +[Mount] +What=var_overlay_tmpfs +Where=/run/buildroot/mounts/var +Type=tmpfs +Options=private +LazyUnmount=truepackage/skeleton-init-systemd/overlayfs/var.mount new file +14
-0@@ -0,0 +1,14 @@ +[Unit] +Description=Variable storage overlay +Documentation=man:file-hierarchy(7) +ConditionPathIsSymbolicLink=!/var +DefaultDependencies=no +After=prepare-var-overlay.service +BindsTo=prepare-var-overlay.service + +[Mount] +What=overlay_var +Where=/var +Type=overlay +Options=lowerdir=/run/buildroot/mounts/var/lower,upperdir=/run/buildroot/mounts/var/upper,workdir=/run/buildroot/mounts/var/work,redirect_dir=on,index=on,xino=on +LazyUnmount=truepackage/skeleton-init-systemd/skeleton-init-systemd.mk +25
-3@@ -33,7 +33,7 @@ endef # a real (but empty) directory, and the "factory files" will be copied # back there by the tmpfiles.d mechanism. ifeq ($(BR2_INIT_SYSTEMD_VAR_FACTORY),y) -define SKELETON_INIT_SYSTEMD_PRE_ROOTFS_VAR +define SKELETON_INIT_SYSTEMD_PRE_ROOTFS_VAR_FACTORY rm -rf $(TARGET_DIR)/usr/share/factory/var mv $(TARGET_DIR)/var $(TARGET_DIR)/usr/share/factory/var mkdir -p $(TARGET_DIR)/var@@ -52,11 +52,33 @@ define SKELETON_INIT_SYSTEMD_PRE_ROOTFS_VAR || exit 1; \ fi; \ done >$(TARGET_DIR)/usr/lib/tmpfiles.d/00-buildroot-var.conf - $(INSTALL) -D -m 0644 $(SKELETON_INIT_SYSTEMD_PKGDIR)/var.mount \ + $(INSTALL) -D -m 0644 $(SKELETON_INIT_SYSTEMD_PKGDIR)/factory/var.mount \ $(TARGET_DIR)/usr/lib/systemd/system/var.mount endef -SKELETON_INIT_SYSTEMD_ROOTFS_PRE_CMD_HOOKS += SKELETON_INIT_SYSTEMD_PRE_ROOTFS_VAR +SKELETON_INIT_SYSTEMD_ROOTFS_PRE_CMD_HOOKS += SKELETON_INIT_SYSTEMD_PRE_ROOTFS_VAR_FACTORY endif # BR2_INIT_SYSTEMD_VAR_FACTORY + +ifeq ($(BR2_INIT_SYSTEMD_VAR_OVERLAYFS),y) + +define SKELETON_INIT_SYSTEMD_LINUX_CONFIG_FIXUPS + $(call KCONFIG_ENABLE_OPT,CONFIG_OVERLAY_FS) +endef + +define SKELETON_INIT_SYSTEMD_PRE_ROOTFS_VAR_OVERLAYFS + $(INSTALL) -D -m 0644 \ + $(SKELETON_INIT_SYSTEMD_PKGDIR)/overlayfs/run-buildroot-mounts-var.mount \ + $(TARGET_DIR)/usr/lib/systemd/system/run-buildroot-mounts-var.mount + $(INSTALL) -D -m 0644 \ + $(SKELETON_INIT_SYSTEMD_PKGDIR)/overlayfs/prepare-var-overlay.service \ + $(TARGET_DIR)/usr/lib/systemd/system/prepare-var-overlay.service + $(INSTALL) -D -m 0644 \ + $(SKELETON_INIT_SYSTEMD_PKGDIR)/overlayfs/var.mount \ + $(TARGET_DIR)/usr/lib/systemd/system/var.mount +endef +SKELETON_INIT_SYSTEMD_POST_INSTALL_TARGET_HOOKS += SKELETON_INIT_SYSTEMD_PRE_ROOTFS_VAR_OVERLAYFS + +endif # BR2_INIT_SYSTEMD_VAR_OVERLAYFS + endif # BR2_TARGET_GENERIC_REMOUNT_ROOTFS_RW ifeq ($(BR2_INIT_SYSTEMD_POPULATE_TMPFILES),y)system/Config.in +19
-8@@ -164,6 +164,14 @@ choice Select how Buildroot provides a read-write /var when the rootfs is not remounted read-write. + Note: Buildroot uses a tmpfs, either as a mount point or as + the upper of an overlayfs, so as to at least make the system + bootable out of the box; mounting a filesystem from actual + storage is left to the integration, as it is too specific and + may need preparatory work like partitionning a device and/or + formatting a filesystem first, which falls out of the scope + of Buildroot. + config BR2_INIT_SYSTEMD_VAR_FACTORY bool "build a factory to populate a tmpfs" help@@ -176,17 +184,21 @@ config BR2_INIT_SYSTEMD_VAR_FACTORY It probably does not play very well with triggering a call to systemd-tmpfiles at build time (below). - Note: Buildroot mounts a tmpfs on /var to at least make the - system bootable out of the box; mounting a filesystem from - actual storage is left to the integration, as it is too - specific and may need preparatory work like partitionning a - device and/or formatting a filesystem first, so that falls - out of the scope of Buildroot. - To use persistent storage, provide a systemd dropin for the var.mount unit, that overrides the What and Type, and possibly the Options and After, fields. +config BR2_INIT_SYSTEMD_VAR_OVERLAYFS + bool "mount an overlayfs backed by a tmpfs" + select BR2_INIT_SYSTEMD_POPULATE_TMPFILES + help + Mount an overlayfs on /var, with the upper as a tmpfs. + + To use a persistent storage, provide a systemd dropin for the + run-buildroot-mounts-var.mount unit, that overrides the What + and Type, and possibly Options, fields, and adds necessary + dependencies on other services. + config BR2_INIT_SYSTEMD_VAR_NONE bool "do nothing" help --
Quoted 2 lines
2.25.1
Just a heads up that I worked on a new version with several cleanups/improvements,
still need to rework it into a proper patch with explanations, hope I will finish it next weekend.
Norbert
_______________________________________________
buildroot mailing list
[email protected]
https://lists.buildroot.org/mailman/listinfo/buildroot
Re: [Buildroot] [PATCH 2/3 v4] system: add option to use an overlayfs on /var on a r/o root w/ systemd
Norbert, All,
On 2023-01-09 00:26 +0100, Norbert Lange spake thusly:
Quoted 12 lines
Am So., 25. Dez. 2022 um 23:08 Uhr schrieb Yann E. MORIN <[email protected]>:
Quoted 10 lines
From: "Yann E. MORIN" <[email protected]>
While the /var factory seems to be working in most cases, there have been suggestions that it may be slightly and subtely borken in some (rare? edge?) cases, especially about symlinks.
An other solution is to pre-populate /var at build time, by way of calling systemd-tmpfiles, and mounting an overlayfs on-top of it at runtime. The first part is already done, and this change focuses on mountig the overlayfs.
[--SNIP--]
Quoted 4 lines
Just a heads up that I worked on a new version with several cleanups/improvements,
still need to rework it into a proper patch with explanations, hope I will finish it next weekend.
Cool! :-) Do not hesitate to grab whatever explanations I provided above, that are still relevant to your changes, and drop whatever was wrong or not longer fits.
Will you base that over this series, so that it fits within the choice introduced in the previous patch? I hope the choice can be applied by the end of the week.
Regards,
Yann E. MORIN.
Signature · 26 lines
____________ .-----------------.--------------------: _ :------------------. | Yann E. MORIN | Real-Time Embedded | __/ ) | /"\ ASCII RIBBON | | | Software Designer | _/ - /' | \ / CAMPAIGN | | +33 638.411.245 '--------------------: (_ `--, | X AGAINST | | yann.morin (at) orange.com |_=" ,--' | / \ HTML MAIL | '--------------------------------------:______/_____:------------------' _________________________________________________________________________________________________________________________ Ce message et ses pieces jointes peuvent contenir des informations confidentielles ou privilegiees et ne doivent donc pas etre diffuses, exploites ou copies sans autorisation. Si vous avez recu ce message par erreur, veuillez le signaler a l'expediteur et le detruire ainsi que les pieces jointes. Les messages electroniques etant susceptibles d'alteration, Orange decline toute responsabilite si ce message a ete altere, deforme ou falsifie. Merci. This message and its attachments may contain confidential or privileged information that may be protected by law; they should not be distributed, used or copied without authorisation. If you have received this email in error, please notify the sender and delete this message and its attachments. As emails may be altered, Orange is not liable for messages that have been modified, changed or falsified. Thank you. _______________________________________________ buildroot mailing list [email protected] https://lists.buildroot.org/mailman/listinfo/buildroot
PATCH v4 3/3 support/testing: add systemd tests for factory and overlayfs
In reply to Yann E. MORIN--- .../conf/overlayfs-kernel-fragment.config | 1 + .../base.conf | 2 + support/testing/tests/init/test_systemd.py | 209 +++++++++++++++++- 3 files changed, 203 insertions(+), 9 deletions(-) create mode 100644 support/testing/conf/overlayfs-kernel-fragment.config create mode 100644 support/testing/tests/init/systemd-overlay/usr/lib/systemd/system/run-buildroot-mounts-var.mount.d/base.conf
support/testing/conf/overlayfs-kernel-fragment.config new file +1 -0
@@ -0,0 +1 @@ +CONFIG_OVERLAY_FS=y
support/testing/tests/init/systemd-overlay/usr/lib/systemd/system/run-buildroot-mounts-var.mount.d/base.conf new file +2 -0
@@ -0,0 +1,2 @@ +[Mount] +What=other-var-backing-store
support/testing/tests/init/test_systemd.py +200 -9
236 lines not on this page · raw message
Signature · 6 lines
2.25.1 _______________________________________________ buildroot mailing list [email protected] https://lists.buildroot.org/mailman/listinfo/buildroot
Quoted 37 lines · Yann E. MORIN
Hello All!
This three-patch series introduces an alternate option to handle /var as an overlayfs, when using a read-only rootfs with systemd.
The rationale behind wanting to use an overlayfs rather than the factory we used to create so far, is that in some corner-cases, the factory does not work, and can't easily be fixed (mesmerising hand-waving...), while the overlayfs Just-Works™ (at the expense of a little trickery at runtime).
This series would not have been entirely possible without the input from Norbert, who provided the basis for the overlayfs-based solution, and explanations on how things fit together in a systemd system. Thanks!
Changes v3 -> v4:
- drop patches already applied
- split mounting the base tmpfs out of the service unit and into its own .mount unit
- rename the service unit to a more appropriate name
- update explanations on hos to provide one's own backing store instead of the tmpfsChanges v2 -> v3:
- introduce the overlayfs-based proposal from Norbert
- some rewording
- some typo fixes (yah, Yann being Yann being me...)Changes v1 -> v2:
- split Yann@work initial patch into the first two patch
- move the systemd-tmpfile handling to the skeleton
- introduce options to enable/disable factory or systemd-tmpfilesRegards,
Yann E. MORIN.
Quoted 5 lines
----------------------------------------------------------------
Yann E. MORIN (3):
system: introduce a choice for /var management
system: add option to use an overlayfs on /var on a r/o root w/ systemd support/testing: add systemd tests for factory and overlayfs
Series applied to master, thanks, with a number of modifications:
On the overlayfs patch:
- Merge commit messages from Yann and from Norbert.
- Remove the run-buildroot-mounts-var.mount unit; instead, just reuse the existing tmpfs for the upper layer in the default case.
- Update the help text to explain how to mount a custom upper layer with fstab.
On the test patch:
- use a simple mount unit for TestInitSystemSystemdRoFullOverlayfsVarBacking;
- change the test of TestInitSystemSystemdRoFullOverlayfsVarBacking to check that the exact expected mount was performed;
- add a test of var backing with fstab instead of mount unit.
Regards,
Arnout
Quoted 11 lines
.../skeleton-init-systemd/{ => factory}/var.mount | 0
.../overlayfs/prepare-var-overlay.service | 19 ++
.../overlayfs/run-buildroot-mounts-var.mount | 12 ++
package/skeleton-init-systemd/overlayfs/var.mount | 14 ++
.../skeleton-init-systemd/skeleton-init-systemd.mk | 28 ++-
.../testing/conf/overlayfs-kernel-fragment.config | 1 +
.../run-buildroot-mounts-var.mount.d/base.conf | 2 +
support/testing/tests/init/test_systemd.py | 209 ++++++++++++++++++++-
system/Config.in | 48 ++++-
9 files changed, 311 insertions(+), 22 deletions(-)Quoted 7 lines
rename package/skeleton-init-systemd/{ => factory}/var.mount (100%)
create mode 100644 package/skeleton-init-systemd/overlayfs/prepare-var-overlay.service
create mode 100644 package/skeleton-init-systemd/overlayfs/run-buildroot-mounts-var.mount
create mode 100644 package/skeleton-init-systemd/overlayfs/var.mount
create mode 100644support/testing/conf/overlayfs-kernel-fragment.config
create mode 100644support/testing/tests/init/systemd-overlay/usr/lib/systemd/system/run-buildroot-mounts-var.mount.d/base.conf
_______________________________________________
buildroot mailing list
[email protected]
https://lists.buildroot.org/mailman/listinfo/buildroot