diff mbox series

[v1] udev/udev-extraconf: Fix race in automount cache

Message ID 20250415074212.2559315-1-dse@thaumatec.com
State New
Headers show
Series [v1] udev/udev-extraconf: Fix race in automount cache | expand

Commit Message

Daniel Semkowicz April 15, 2025, 7:42 a.m. UTC
Cache files with names of automounted devices were saved in /tmp
directory, but base directories for mount points are created by default
in the /run/media directory.

With systemd init manager, /tmp is mounted by the systemd service.
Udev has no dependency on /tmp and this creates a race condition.
It is possible that the block device is already present in the device
and theĀ udev rules for automount are triggered during boot
before /tmp is mounted. In such a case, mount cache files are created
on the base file system. If the base file system is read-write,
the cached file persists after the reboot and prevents automount
on the next boot.

Use the mount base directory for storing cache files. Both mount points
and cache will be created in the same place, so there will be no race.

Signed-off-by: Daniel Semkowicz <dse@thaumatec.com>
---
 meta/recipes-core/udev/udev-extraconf/mount.sh | 15 +++++++++------
 1 file changed, 9 insertions(+), 6 deletions(-)
diff mbox series

Patch

diff --git a/meta/recipes-core/udev/udev-extraconf/mount.sh b/meta/recipes-core/udev/udev-extraconf/mount.sh
index 0cbae48729..467703daa4 100644
--- a/meta/recipes-core/udev/udev-extraconf/mount.sh
+++ b/meta/recipes-core/udev/udev-extraconf/mount.sh
@@ -7,6 +7,7 @@ 
 BASE_INIT="`readlink -f "@base_sbindir@/init"`"
 INIT_SYSTEMD="@systemd_unitdir@/systemd"
 MOUNT_BASE="@MOUNT_BASE@"
+AUTOMOUNT_CACHE_DIR="${MOUNT_BASE}/.automount"
 
 if [ "x$BASE_INIT" = "x$INIT_SYSTEMD" ];then
     # systemd as init uses systemd-mount to mount block devices
@@ -60,7 +61,7 @@  automount_systemd() {
 
     # Only go for auto-mounting when the device has been cleaned up in remove
     # or has not been identified yet
-    if [ -e "/tmp/.automount-$name" ]; then
+    if [ -e "${AUTOMOUNT_CACHE_DIR}/$name" ]; then
             logger "mount.sh/automount" "[$MOUNT_BASE/$name] is already cached"
             return
     fi
@@ -104,7 +105,8 @@  automount_systemd() {
         rm_dir "$MOUNT_BASE/$name"
     else
         logger "mount.sh/automount" "Auto-mount of [$MOUNT_BASE/$name] successful"
-        echo "$name" > "/tmp/.automount-$name"
+        [ -d "${AUTOMOUNT_CACHE_DIR}" ] || mkdir "${AUTOMOUNT_CACHE_DIR}"
+        echo "$name" > "${AUTOMOUNT_CACHE_DIR}/$name"
     fi
 }
 
@@ -126,7 +128,7 @@  automount() {
 
         # Only go for auto-mounting when the device has been cleaned up in remove
         # or has not been identified yet
-        if [ -e "/tmp/.automount-$name" ]; then
+        if [ -e "${AUTOMOUNT_CACHE_DIR}/$name" ]; then
                 logger "mount.sh/automount" "[$MOUNT_BASE/$name] is already cached"
                 return
         fi
@@ -162,10 +164,11 @@  automount() {
 		# The actual device might not be present in the remove event so blkid cannot
 		# be used to calculate what name was generated here. Simply save the mount
 		# name in our tmp file.
-		echo "$name" > "/tmp/.automount-$name"
+		[ -d "${AUTOMOUNT_CACHE_DIR}" ] || mkdir "${AUTOMOUNT_CACHE_DIR}"
+        echo "$name" > "${AUTOMOUNT_CACHE_DIR}/$name"
 	fi
 }
-	
+
 rm_dir() {
 	# We do not want to rm -r populated directories
 	if test "`find "$1" | wc -l | tr -d " "`" -lt 2 -a -d "$1"
@@ -206,7 +209,7 @@  fi
 
 if [ "$ACTION" = "remove" ] || [ "$ACTION" = "change" ] && [ -x "$UMOUNT" ] && [ -n "$DEVNAME" ]; then
     name="`basename "$DEVNAME"`"
-    tmpfile=`find /tmp | grep "\.automount-.*${name}$"`
+    tmpfile=`find "${AUTOMOUNT_CACHE_DIR}" -name "*${name}"`
     if [ ! -e "/sys/$DEVPATH" -a -e "$tmpfile" ]; then
         logger "mount.sh/remove" "cleaning up $DEVNAME, was mounted by the auto-mounter"
         for mnt in `cat /proc/mounts | grep "$DEVNAME" | cut -f 2 -d " " `