[meta-mentor] [PATCH 1/1] udev: Add udev rule to handle CHANGE event

Abbas Raza Abbas_Raza at mentor.com
Mon May 20 10:53:57 PDT 2013


When SD card is ejected from card reader without proper unmounting,
kernel does not generate a REMOVE event, instead it generates
a CHANGE event(only if polling is enabled /sys/module/block/parameters/events_dfl_poll_msecs)
and we don't have any udev rule in automount.rules to handle this,
so partitions never get unmounted. unmounting of partitions can be done
if udev rules handle this CHANGE event.

Signed-off-by: Abbas Raza <Abbas_Raza at mentor.com>
---
 recipes/udev/udev-extraconf/automount.rules | 19 +++++++
 recipes/udev/udev-extraconf/mount.sh        | 82 +++++++++++++++++++++++++++++
 recipes/udev/udev-extraconf_1.0.bbappend    | 15 ++++++
 3 files changed, 116 insertions(+)
 create mode 100644 recipes/udev/udev-extraconf/automount.rules
 create mode 100644 recipes/udev/udev-extraconf/mount.sh
 create mode 100644 recipes/udev/udev-extraconf_1.0.bbappend

diff --git a/recipes/udev/udev-extraconf/automount.rules b/recipes/udev/udev-extraconf/automount.rules
new file mode 100644
index 0000000..62578ea
--- /dev/null
+++ b/recipes/udev/udev-extraconf/automount.rules
@@ -0,0 +1,19 @@
+# There are a number of modifiers that are allowed to be used in some
+# of the different fields. They provide the following subsitutions:
+#
+# %n the "kernel number" of the device.
+#    For example, 'sda3' has a "kernel number" of '3'
+# %e the smallest number for that name which does not matches an existing node
+# %k the kernel name for the device
+# %M the kernel major number for the device
+# %m the kernel minor number for the device
+# %b the bus id for the device
+# %c the string returned by the PROGRAM
+# %s{filename} the content of a sysfs attribute
+# %% the '%' char itself
+#
+
+# Media automounting
+SUBSYSTEM=="block", ACTION=="add"    RUN+="/etc/udev/scripts/mount.sh"
+SUBSYSTEM=="block", ACTION=="remove" RUN+="/etc/udev/scripts/mount.sh"
+SUBSYSTEM=="block", ACTION=="change", ENV{DISK_MEDIA_CHANGE}=="1" RUN+="/etc/udev/scripts/mount.sh"
diff --git a/recipes/udev/udev-extraconf/mount.sh b/recipes/udev/udev-extraconf/mount.sh
new file mode 100644
index 0000000..13ce3b6
--- /dev/null
+++ b/recipes/udev/udev-extraconf/mount.sh
@@ -0,0 +1,82 @@
+#!/bin/sh
+#
+# Called from udev
+#
+# Attempt to mount any added block devices and umount any removed devices
+
+
+MOUNT="/bin/mount"
+PMOUNT="/usr/bin/pmount"
+UMOUNT="/bin/umount"
+
+for line in `cat /etc/udev/mount.blacklist`
+do
+	if [ ` expr match "$DEVNAME" "$line" ` -gt 0 ];
+	then
+		logger "udev/mount.sh" "[$DEVNAME] is blacklisted, ignoring"
+		exit 0
+	fi
+done
+
+automount() {
+	name="`basename "$DEVNAME"`"
+
+	! test -d "/media/$name" && mkdir -p "/media/$name"
+
+	if ! $MOUNT -t auto -o sync $DEVNAME "/media/$name"
+	then
+		#logger "mount.sh/automount" "$MOUNT -t auto $DEVNAME \"/media/$name\" failed!"
+		rm_dir "/media/$name"
+	else
+		logger "mount.sh/automount" "Auto-mount of [/media/$name] successful"
+		touch "/tmp/.automount-$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"
+	then
+		! test -z "$1" && rm -r "$1"
+	else
+		logger "mount.sh/automount" "Not removing non-empty directory [$1]"
+	fi
+}
+
+if [ "$ACTION" = "add" ] && [ -n "$DEVNAME" ]; then
+	if [ -x "$PMOUNT" ]; then
+		$PMOUNT $DEVNAME 2> /dev/null
+	elif [ -x $MOUNT ]; then
+		$MOUNT $DEVNAME 2> /dev/null
+	fi
+
+	# If the device isn't mounted at this point, it isn't configured in fstab
+	grep -q "^$DEVNAME " /proc/mounts || automount
+fi
+
+
+
+if [ "$ACTION" = "remove" ] && [ -x "$UMOUNT" ] && [ -n "$DEVNAME" ]; then
+	for mnt in `cat /proc/mounts | grep "$DEVNAME" | cut -f 2 -d " " `
+	do
+		$UMOUNT $mnt
+	done
+
+	# Remove empty directories from auto-mounter
+	name="`basename "$DEVNAME"`"
+	test -e "/tmp/.automount-$name" && rm_dir "/media/$name"
+fi
+
+if [ "$ACTION" = "change" ] && [ -x "$UMOUNT" ] && [ -n "$DEVNAME" ]; then
+	for mnt in `cat /proc/mounts | grep "$DEVNAME" | cut -f 2 -d " " `
+	do
+		$UMOUNT $mnt
+	done
+
+	# Remove empty directories from auto-mounter
+	name="`basename "$DEVNAME"`"
+	for mnt in `ls /tmp/.automount* | grep "$name" | cut -f 2 -d "-"`
+	do
+		rm_dir "/media/$mnt"
+	done
+fi
diff --git a/recipes/udev/udev-extraconf_1.0.bbappend b/recipes/udev/udev-extraconf_1.0.bbappend
new file mode 100644
index 0000000..3fd2911
--- /dev/null
+++ b/recipes/udev/udev-extraconf_1.0.bbappend
@@ -0,0 +1,15 @@
+FILESEXTRAPATHS_prepend := "${THISDIR}/${PN}:"
+
+PRINC := "${@int(PRINC) + 1}"
+
+SRC_URI_append = " file://automount.rules \
+			file://mount.sh \
+"
+
+do_install_prepend () {
+	install -d ${D}${sysconfdir}/udev/rules.d
+	install -m 0644 ${WORKDIR}/automount.rules ${D}${sysconfdir}/udev/rules.d
+
+	install -d ${D}${sysconfdir}/udev/scripts/
+	install -m 0755 ${WORKDIR}/mount.sh ${D}${sysconfdir}/udev/scripts/mount.sh
+}
-- 
1.8.2




More information about the meta-mentor mailing list