diff mbox series

[v3,3/3] oe-selftest: overlayfs: Add a demo case for /etc

Message ID 20260114185508.380709-4-uvv.mail@gmail.com
State New
Headers show
Series Overlayfs improvements | expand

Commit Message

Vyacheslav Yurkov Jan. 14, 2026, 6:54 p.m. UTC
From: Vyacheslav Yurkov <uvv.mail@gmail.com>

/etc is a special directory. It's possible to create a mount unit for
it, but many system services that start early at boot time will not
rescan its content when you mount overlay on top. The added test case
demonstrates this by adding a sample systemd service and enabling it in
overlay.

Signed-off-by: Vyacheslav Yurkov <uvv.mail@gmail.com>
---
 meta/lib/oeqa/selftest/cases/overlayfs.py | 98 +++++++++++++++++++++++
 1 file changed, 98 insertions(+)

Comments

Paul Barker Jan. 15, 2026, 2:01 p.m. UTC | #1
On Wed, 2026-01-14 at 18:54 +0000, Vyacheslav Yurkov via
lists.openembedded.org wrote:
> From: Vyacheslav Yurkov <uvv.mail@gmail.com>
> 
> /etc is a special directory. It's possible to create a mount unit for
> it, but many system services that start early at boot time will not
> rescan its content when you mount overlay on top. The added test case
> demonstrates this by adding a sample systemd service and enabling it in
> overlay.

Hi,

I still don't understand what we're actually trying to test here. We
know that overlayfs.bbclass can't be used this way. The documentation
already says "The class does not support the /etc directory itself" and
points users at the overlayfs-etc class. What do we gain by having a
test case for this?

Perhaps what we should have is a check at build time to catch '/etc/' in
an OVERLAYFS_MOUNT_POINT entry, which prints an error telling the user
to use overlayfs-etc instead. That way the runtime misbehaviour is
actually prevented.

> 
> Signed-off-by: Vyacheslav Yurkov <uvv.mail@gmail.com>
> ---
>  meta/lib/oeqa/selftest/cases/overlayfs.py | 98 +++++++++++++++++++++++
>  1 file changed, 98 insertions(+)
> 
> diff --git a/meta/lib/oeqa/selftest/cases/overlayfs.py b/meta/lib/oeqa/selftest/cases/overlayfs.py
> index 3e55e97927..426b4ccee3 100644
> --- a/meta/lib/oeqa/selftest/cases/overlayfs.py
> +++ b/meta/lib/oeqa/selftest/cases/overlayfs.py
> @@ -263,6 +263,104 @@ EOT
>  
>          self._test_correct_image('systemd-machine-units', systemd_machine_unit_append)
>  
> +    @skipIfNotMachine("qemux86-64", "tests are qemux86-64 specific currently")
> +    def test_etc_mount(self):
> +        """
> +        Summary:   /etc is not supposed to be used with overlayfs.bbclass
> +        Expected:  Observe inconsistencies after using etc overlay with a mount unit
> +        Author:    Vyacheslav Yurkov <uvv.mail@gmail.com>
> +        """
> +        systemd_machine_unit_append = """
> +SYSTEMD_SERVICE:${PN} += " \
> +    data.mount \
> +    etc.mount \
> +"
> +
> +do_install:append() {
> +    install -d ${D}${systemd_system_unitdir}
> +    install -d ${D}${ROOT_HOME}
> +    cat <<EOT > ${D}${systemd_system_unitdir}/etc.mount
> +[Unit]
> +Description=OverlayFS mount for /etc directory
> +DefaultDependencies=no
> +RequiresMountsFor=/data
> +
> +[Mount]
> +What=overlay
> +Where=/etc
> +Type=overlay
> +Options=lowerdir=/etc,upperdir=/data/overlay/etc,workdir=/data/overlay-workdir/etc
> +[Install]
> +WantedBy=local-fs.target
> +EOT
> +
> +    cat <<EOT >${D}${systemd_system_unitdir}/data.mount
> +[Unit]
> +Description=Persistent storage partition
> +
> +[Mount]
> +What=/dev/sda3
> +Where=/data
> +Type=ext4
> +Options=defaults
> +
> +[Install]
> +WantedBy=local-fs.target
> +EOT
> +    cat <<EOT > ${D}${ROOT_HOME}/test-daemon.service
> +[Unit]
> +Description=My one-shot task
> +After=local-fs.target
> +
> +[Service]
> +Type=oneshot
> +ExecStart=/usr/bin/echo test
> +RemainAfterExit=yes
> +
> +[Install]
> +WantedBy=multi-user.target
> +EOT
> +}
> +
> +FILES:${PN} += "${ROOT_HOME}"
> +"""
> +
> +        config = """
> +IMAGE_INSTALL:append = " systemd-machine-units"
> +DISTRO_FEATURES:append = " overlayfs"
> +
> +# Use systemd as init manager
> +INIT_MANAGER = "systemd"
> +
> +# enable overlayfs in the kernel
> +KERNEL_EXTRA_FEATURES:append = " features/overlayfs/overlayfs.scc"
> +
> +IMAGE_FSTYPES += "wic"
> +WKS_FILE = "overlayfs_etc.wks.in"
> +OVERLAYFS_ROOTFS_TYPE = "ext4"
> +"""
> +
> +        self.write_config(config)
> +
> +        machine_inc = """
> +OVERLAYFS_MOUNT_POINT[etc] = "/etc"
> +OVERLAYFS_QA_SKIP[mnt-overlay] = "mount-configured"
> +"""
> +        self.set_machine_config(machine_inc)
> +        self.write_recipeinc('systemd-machine-units', systemd_machine_unit_append)
> +        bitbake('core-image-minimal')
> +        with runqemu('core-image-minimal', image_fstype='wic', discard_writes=False) as qemu:
> +            test_daemon_path = get_bb_var('ROOT_HOME') + '/test-daemon.service'
> +            status, output = qemu.run_serial('cp -f ' + test_daemon_path + ' /etc/systemd/system/')
> +            status, output = qemu.run_serial("systemctl enable test-daemon")
> +            status, output = qemu.run_serial("sync")
> +        with runqemu('core-image-minimal', image_fstype='wic') as qemu:
> +            # Check the test service status. It's enabled and supposed to start, but it didn't
> +            status, output = qemu.run_serial("systemctl is-enabled test-daemon")
> +            self.assertTrue("enabled" in output, msg=output)
> +            status, output = qemu.run_serial("systemctl is-active test-daemon")
> +            self.assertTrue("inactive" in output, msg=output)
> +
>  @OETestTag("runqemu")
>  class OverlayFSEtcRunTimeTests(OESelftestTestCase):
>      """overlayfs-etc class tests"""

Best regards,
diff mbox series

Patch

diff --git a/meta/lib/oeqa/selftest/cases/overlayfs.py b/meta/lib/oeqa/selftest/cases/overlayfs.py
index 3e55e97927..426b4ccee3 100644
--- a/meta/lib/oeqa/selftest/cases/overlayfs.py
+++ b/meta/lib/oeqa/selftest/cases/overlayfs.py
@@ -263,6 +263,104 @@  EOT
 
         self._test_correct_image('systemd-machine-units', systemd_machine_unit_append)
 
+    @skipIfNotMachine("qemux86-64", "tests are qemux86-64 specific currently")
+    def test_etc_mount(self):
+        """
+        Summary:   /etc is not supposed to be used with overlayfs.bbclass
+        Expected:  Observe inconsistencies after using etc overlay with a mount unit
+        Author:    Vyacheslav Yurkov <uvv.mail@gmail.com>
+        """
+        systemd_machine_unit_append = """
+SYSTEMD_SERVICE:${PN} += " \
+    data.mount \
+    etc.mount \
+"
+
+do_install:append() {
+    install -d ${D}${systemd_system_unitdir}
+    install -d ${D}${ROOT_HOME}
+    cat <<EOT > ${D}${systemd_system_unitdir}/etc.mount
+[Unit]
+Description=OverlayFS mount for /etc directory
+DefaultDependencies=no
+RequiresMountsFor=/data
+
+[Mount]
+What=overlay
+Where=/etc
+Type=overlay
+Options=lowerdir=/etc,upperdir=/data/overlay/etc,workdir=/data/overlay-workdir/etc
+[Install]
+WantedBy=local-fs.target
+EOT
+
+    cat <<EOT >${D}${systemd_system_unitdir}/data.mount
+[Unit]
+Description=Persistent storage partition
+
+[Mount]
+What=/dev/sda3
+Where=/data
+Type=ext4
+Options=defaults
+
+[Install]
+WantedBy=local-fs.target
+EOT
+    cat <<EOT > ${D}${ROOT_HOME}/test-daemon.service
+[Unit]
+Description=My one-shot task
+After=local-fs.target
+
+[Service]
+Type=oneshot
+ExecStart=/usr/bin/echo test
+RemainAfterExit=yes
+
+[Install]
+WantedBy=multi-user.target
+EOT
+}
+
+FILES:${PN} += "${ROOT_HOME}"
+"""
+
+        config = """
+IMAGE_INSTALL:append = " systemd-machine-units"
+DISTRO_FEATURES:append = " overlayfs"
+
+# Use systemd as init manager
+INIT_MANAGER = "systemd"
+
+# enable overlayfs in the kernel
+KERNEL_EXTRA_FEATURES:append = " features/overlayfs/overlayfs.scc"
+
+IMAGE_FSTYPES += "wic"
+WKS_FILE = "overlayfs_etc.wks.in"
+OVERLAYFS_ROOTFS_TYPE = "ext4"
+"""
+
+        self.write_config(config)
+
+        machine_inc = """
+OVERLAYFS_MOUNT_POINT[etc] = "/etc"
+OVERLAYFS_QA_SKIP[mnt-overlay] = "mount-configured"
+"""
+        self.set_machine_config(machine_inc)
+        self.write_recipeinc('systemd-machine-units', systemd_machine_unit_append)
+        bitbake('core-image-minimal')
+        with runqemu('core-image-minimal', image_fstype='wic', discard_writes=False) as qemu:
+            test_daemon_path = get_bb_var('ROOT_HOME') + '/test-daemon.service'
+            status, output = qemu.run_serial('cp -f ' + test_daemon_path + ' /etc/systemd/system/')
+            status, output = qemu.run_serial("systemctl enable test-daemon")
+            status, output = qemu.run_serial("sync")
+        with runqemu('core-image-minimal', image_fstype='wic') as qemu:
+            # Check the test service status. It's enabled and supposed to start, but it didn't
+            status, output = qemu.run_serial("systemctl is-enabled test-daemon")
+            self.assertTrue("enabled" in output, msg=output)
+            status, output = qemu.run_serial("systemctl is-active test-daemon")
+            self.assertTrue("inactive" in output, msg=output)
+
 @OETestTag("runqemu")
 class OverlayFSEtcRunTimeTests(OESelftestTestCase):
     """overlayfs-etc class tests"""