Add an overlayfs on /etc for read-only root filesystems
cover Add an overlayfs on /etc for read-only root filesystems
This series adds BR2_ROOTFS_OVERLAYFS_ETC, which mounts an overlayfs on /etc, with its upper layer on a persistent device, before the init system starts. It works with busybox init, sysvinit and systemd.
It is modeled after the overlayfs-etc image feature of openembedded-core (meta/classes-recipe/overlayfs-etc.bbclass and meta/files/overlayfs-etc-preinit.sh.in), which works the same way, independently of the init system:
- the original init is moved aside, and a pre-init script is installed as /sbin/init;
- at boot, the pre-init mounts the persistent device on a mount point (/data by default), mounts the overlayfs on /etc, with its upper and work directories in <mount point>/overlay-etc/, and optionally exposes the original /etc read-only in <mount point>/overlay-etc/lower;
- it then execs the original init, which starts with a writable /etc.
The pre-init script is adapted from the openembedded-core one, and the options mirror its variables (OVERLAYFS_ETC_DEVICE, _FSTYPE, _MOUNT_OPTIONS, _MOUNT_POINT, _EXPOSE_LOWER). It differs on a few points:
- the original init is moved to /usr/libexec/overlayfs-etc/init rather than renamed to /sbin/init.orig, as busybox selects its applet from the name it is called with;
- the mount point is created at build time, so the pre-init does not need to remount the root filesystem read-write (OVERLAYFS_ETC_CREATE_MOUNT_DIRS);
- the overlayfs options are passed in a single -o, as expected by the busybox mount.
As for the /var overlayfs, the options are in the system menu, and the implementation, including the kernel config fixup enabling overlayfs, is in the skeleton, here skeleton-init-common, as the pre-init does not depend on the init system. Only /etc is handled: /var keeps the existing handling.
The persistent device must exist and be formatted, which is left to the integration. If it cannot be mounted, the system boots with the read-only /etc.
Angelo Compagnucci (3):
package/skeleton-init-common: add option to mount an overlayfs on /etc docs/manual: document the /etc overlayfs
support/testing: add runtime tests for the /etc overlayfs
DEVELOPERS | 1 + docs/manual/configure.adoc | 32 +++++ .../overlayfs-etc-preinit.sh | 39 ++++++ .../skeleton-init-common.mk | 63 +++++++++ .../testing/tests/init/test_overlayfs_etc.py | 128 ++++++++++++++++++ .../linux-no-overlayfs.fragment | 2 + system/Config.in | 62 +++++++++ 7 files changed, 327 insertions(+) create mode 100644 package/skeleton-init-common/overlayfs-etc-preinit.sh create mode 100644 support/testing/tests/init/test_overlayfs_etc.py create mode 100644 support/testing/tests/init/test_overlayfs_etc/linux-no-overlayfs.fragment
Signature · 6 lines
2.34.1 _______________________________________________ buildroot mailing list [email protected] https://lists.buildroot.org/mailman/listinfo/buildroot
PATCH 1/3 package/skeleton-init-common: add option to mount an overlayfs on /etc
On a read-only root filesystem, only /var can be made writable, and only with systemd. /etc cannot be mounted from /etc/fstab or from a systemd unit, as the init system already needs it when it starts.
Add an option to mount an overlayfs on /etc, with its upper layer on a persistent device, for the busybox, sysvinit and systemd init systems, as done by the overlayfs-etc image feature of openembedded-core: the init program is moved to /usr/libexec/overlayfs-etc/init, keeping its name as busybox selects its applet from it, and a pre-init script, adapted from openembedded-core, is installed as /sbin/init. It mounts the persistent device, mounts the overlayfs on /etc, optionally exposes the original /etc read-only, and then starts the original init.
This is done in skeleton-init-common, as the pre-init does not depend on the init system, and overlayfs support is enabled in the kernel with a package kernel config fixup, as done for the /var overlayfs.
The persistent device must exist and be formatted, which is left to the integration. If it cannot be mounted, the system boots with the read-only /etc.
--- .../overlayfs-etc-preinit.sh | 39 ++++++++++++ .../skeleton-init-common.mk | 63 +++++++++++++++++++ system/Config.in | 62 ++++++++++++++++++ 3 files changed, 164 insertions(+) create mode 100644 package/skeleton-init-common/overlayfs-etc-preinit.sh
package/skeleton-init-common/overlayfs-etc-preinit.sh new file +39 -0
@@ -0,0 +1,39 @@ +#!/bin/sh +# BR2_ROOTFS_OVERLAYFS_ETC pre-init +# +# Mount an overlayfs on /etc, with its upper layer on a persistent +# device, before starting the init system, which already needs /etc. +# +# Adapted from overlayfs-etc-preinit.sh.in from openembedded-core. + +PATH=/sbin:/bin:/usr/sbin:/usr/bin + +MOUNT_POINT="@MOUNT_POINT@" +OVERLAY_DIR="${MOUNT_POINT}/overlay-etc" + +echo "overlayfs-etc: mounting @DEVICE@ on ${MOUNT_POINT}" + +mount -t proc proc /proc +mount -t sysfs sysfs /sys + +if mount -n -t "@FSTYPE@" -o "@MOUNT_OPTIONS@" "@DEVICE@" "${MOUNT_POINT}"; then + mkdir -p "${OVERLAY_DIR}/upper" "${OVERLAY_DIR}/work" + + if @EXPOSE_LOWER@; then + # Read-only access to the original /etc content + mkdir -p "${OVERLAY_DIR}/lower" + mount -n -o bind,ro /etc "${OVERLAY_DIR}/lower" + fi + + mount -n -t overlay \ + -o "lowerdir=/etc,upperdir=${OVERLAY_DIR}/upper,workdir=${OVERLAY_DIR}/work,index=off,xino=off,redirect_dir=off,metacopy=off" \ + overlay-etc /etc || + echo "overlayfs-etc: mounting the /etc overlay failed" +else + echo "overlayfs-etc: mounting @DEVICE@ failed, /etc is not writable" +fi + +umount /sys +umount /proc + +exec @INIT@ "$@"
package/skeleton-init-common/skeleton-init-common.mk +63 -0
67 lines not on this page · raw message
system/Config.in +62 -0
68 lines not on this page · raw message
Signature · 6 lines
2.34.1 _______________________________________________ buildroot mailing list [email protected] https://lists.buildroot.org/mailman/listinfo/buildroot
PATCH 2/3 docs/manual: document the /etc overlayfs
In reply to Angelo CompagnucciExplain how the /etc overlayfs works, the options to configure it, the requirements on the persistent device, and that only /etc is handled.
--- docs/manual/configure.adoc | 32 ++++++++++++++++++++++++++++++++ 1 file changed, 32 insertions(+)
docs/manual/configure.adoc +32 -0
@@ -429,3 +429,35 @@ can be chosen from +System configuration+, +Init system+: The solution recommended by Buildroot developers is to use the *BusyBox init* as it is sufficient for most embedded systems. *systemd* can be used for more complex situations. + +==== Writable /etc on a read-only root filesystem + +When the root filesystem stays read-only (+BR2_TARGET_GENERIC_REMOUNT_ROOTFS_RW+ +disabled), +/etc+ can still be made writable with an overlayfs whose +upper layer is on a persistent device, by enabling ++BR2_ROOTFS_OVERLAYFS_ETC+. This works with the BusyBox, systemV and +systemd init systems. + +The init system reads +/etc+ as soon as it starts, so the overlay +can't be mounted from +/etc/fstab+ or from a systemd unit. Instead, +Buildroot moves the init program to +/usr/libexec/overlayfs-etc/init+ +and installs a small script as +/sbin/init+, which: + + * mounts the persistent device (+BR2_ROOTFS_OVERLAYFS_ETC_DEVICE+, + +BR2_ROOTFS_OVERLAYFS_ETC_FSTYPE+, +BR2_ROOTFS_OVERLAYFS_ETC_MOUNT_OPTIONS+) + on +BR2_ROOTFS_OVERLAYFS_ETC_MOUNT_POINT+ (+/data+ by default); + * mounts an overlayfs on +/etc+, with the original +/etc+ as the lower + layer and +<mount point>/overlay-etc/upper+ as the upper layer; + * optionally (+BR2_ROOTFS_OVERLAYFS_ETC_EXPOSE_LOWER+), bind-mounts the + original +/etc+ read-only on +<mount point>/overlay-etc/lower+; + * starts the original init program. + +The persistent device must already exist and be formatted, which is +left to the integration, and it must not be listed in +/etc/fstab+. +If it cannot be mounted, the system still boots, with a read-only ++/etc+. + +Only +/etc+ is handled. With systemd, +/var+ is managed by the ++/var management+ option. With BusyBox or systemV init, +/var+ only +provides volatile directories (symbolic links to +/tmp+ and +/run+), +and +/var/lib+ stays read-only.
Signature · 6 lines
2.34.1 _______________________________________________ buildroot mailing list [email protected] https://lists.buildroot.org/mailman/listinfo/buildroot
PATCH 3/3 support/testing: add runtime tests for the /etc overlayfs
In reply to Angelo CompagnucciTest the /etc overlayfs with the busybox, sysvinit and systemd init systems, with a read-only ext4 root filesystem and a second ext4 disk as the persistent device: the original init runs as PID 1, /etc is an overlay whose changes are stored on the persistent device and survive a reboot, and the original /etc is exposed read-only. Also check that the system still boots, with a read-only /etc, without the persistent device.
The kernel configuration disables overlayfs, to check that the option enables it.
--- DEVELOPERS | 1 + .../testing/tests/init/test_overlayfs_etc.py | 128 ++++++++++++++++++ .../linux-no-overlayfs.fragment | 2 + 3 files changed, 131 insertions(+) create mode 100644 support/testing/tests/init/test_overlayfs_etc.py create mode 100644 support/testing/tests/init/test_overlayfs_etc/linux-no-overlayfs.fragment
DEVELOPERS +1 -0
@@ -262,6 +262,7 @@ F: package/sshguard/ F: package/sunwait/ F: package/sysdig/ F: package/uthash/ +F: support/testing/tests/init/test_overlayfs_etc.py N: Andy Shevchenko <[email protected]> F: package/fb-test-app/
support/testing/tests/init/test_overlayfs_etc.py new file +128 -0
128 lines not on this page · raw message
support/testing/tests/init/test_overlayfs_etc/linux-no-overlayfs.fragment new file +2 -0
@@ -0,0 +1,2 @@ +# Disabled here, to check that BR2_ROOTFS_OVERLAYFS_ETC enables it +# CONFIG_OVERLAY_FS is not set
Signature · 6 lines
2.34.1 _______________________________________________ buildroot mailing list [email protected] https://lists.buildroot.org/mailman/listinfo/buildroot