]> git.ipfire.org Git - thirdparty/dracut-ng.git/commitdiff
fix(overlayfs): unmount NEWROOT before mounting overlay main
authorBenjamin Drung <benjamin.drung@canonical.com>
Mon, 13 Apr 2026 11:15:14 +0000 (13:15 +0200)
committerNeal Gompa (ニール・ゴンパ) <ngompa13@gmail.com>
Thu, 16 Apr 2026 10:56:06 +0000 (06:56 -0400)
When using `rd.overlay` the mount point `/run/rootfsbase` is not
accessible any more, because `LiveOS_rootfs` is mounted over it. This is
`/proc/mounts` from the `tmpfs overlay (rd.overlay)` test case:

```
tmpfs /run tmpfs rw,nosuid,nodev,size=194628k,nr_inodes=819200,mode=755,inode64 0 0
/dev/sda /run/rootfsbase ext4 ro,relatime 0 0
LiveOS_rootfs / overlay rw,relatime,lowerdir=/run/rootfsbase,upperdir=/run/overlayfs,workdir=/run/ovlwork,uuid=on,nouserxattr 0 0
LiveOS_rootfs /run/rootfsbase overlay rw,relatime,lowerdir=/run/rootfsbase,upperdir=/run/overlayfs,workdir=/run/ovlwork,uuid=on,nouserxattr 0 0
devtmpfs /dev devtmpfs rw,nosuid,size=159436k,nr_inodes=39859,mode=755,inode64 0 0
tmpfs /dev/shm tmpfs rw,nosuid,nodev,inode64,usrquota 0 0
devpts /dev/pts devpts rw,nosuid,noexec,relatime,gid=5,mode=600,ptmxmode=000 0 0
sysfs /sys sysfs rw,nosuid,nodev,noexec,relatime 0 0
securityfs /sys/kernel/security securityfs rw,nosuid,nodev,noexec,relatime 0 0
cgroup2 /sys/fs/cgroup cgroup2 rw,nosuid,nodev,noexec,relatime,nsdelegate,memory_recursiveprot,memory_hugetlb_accounting 0 0
none /sys/fs/pstore pstore rw,nosuid,nodev,noexec,relatime 0 0
efivarfs /sys/firmware/efi/efivars efivarfs rw,nosuid,nodev,noexec,relatime 0 0
bpf /sys/fs/bpf bpf rw,nosuid,nodev,noexec,relatime,mode=700 0 0
configfs /sys/kernel/config configfs rw,nosuid,nodev,noexec,relatime 0 0
proc /proc proc rw,nosuid,nodev,noexec,relatime 0 0
```

This breaks use cases where the underlying needs to be accessed.

Bug-Ubuntu: https://launchpad.net/bugs/2147471

modules.d/70overlayfs/mount-overlayfs.sh
test/TEST-21-OVERLAYFS/assertion.sh

index 6adc2d7b18c519f8653be9b1410e9a6cfca34f66..c76dd60d003520674a0d7e9f460017a5548d541d 100755 (executable)
@@ -25,4 +25,7 @@ if strstr "$(cat /proc/mounts)" LiveOS_rootfs; then
     return 0
 fi
 
+if incol2 /proc/mounts "$NEWROOT"; then
+    umount "$NEWROOT"
+fi
 mount -t overlay LiveOS_rootfs -o "$ovlfs",upperdir=/run/overlayfs,workdir=/run/ovlwork "$NEWROOT"
index ba9c86df83814d870877d681440986f6298c13d7..1405db3b0fb2a57777c944e0e9694f4ed17b45f8 100755 (executable)
@@ -1,7 +1,7 @@
 #!/bin/sh
 set -eu
 
-# required binaries: cat grep
+# required binaries: cat cut grep sort
 
 check_crypt_mounted() {
     if ! grep -q "^/dev/mapper/overlay-crypt /run/overlayfs-backing " /proc/mounts; then
@@ -26,6 +26,16 @@ check_crypt_passphrase() {
     fi
 }
 
+check_shadowed_mounts() {
+    local mount previous_mount=
+    cut -d ' ' -f 2 /proc/mounts | sort | while IFS= read -r mount; do
+        if [ "$mount" = "$previous_mount" ]; then
+            echo "Error: $mount found twice in /proc/mounts." >> /run/failed
+        fi
+        previous_mount="$mount"
+    done
+}
+
 if grep -q 'test.expect=none' /proc/cmdline; then
     if grep -q " overlay " /proc/mounts; then
         echo "overlay filesystem found in /proc/mounts" >> /run/failed
@@ -66,6 +76,8 @@ if grep -q 'test.expect=tmpfs-sized' /proc/cmdline; then
     fi
 fi
 
+check_shadowed_mounts
+
 # Dump /proc/mounts at the end if there were any failures for easier debugging
 if [ -s /run/failed ]; then
     {