Udev-extraconf works correctly with sysvinit in the aspect of
automounting block devices,but it has a serious problem in case
of systemd. Block devices automounted by udev are not accessible
to host namespace, i.e. udevd's private namespace. For example,
we cannot format the host namespace block devices.

e.g.
    root@intel-x86-64:~# mkfs.ext4 /dev/sda1
    (skip...)
    /dev/sda1 is apparently in use by the system; will not make a filesystem 
here!

Other distributions have no such problem, because they use a series
of rules to manage block devices. Note that udev-extraconf has just
one file, automount.rules, which results in this problem.

As recommended by members of the systemd community, we can use the
'systemd-mount' command to resolve this problem since it's intended
purpose is to establish (and destroy) transient mount or auto-mount
points using the service manager job queue thereby eliminating
dependencies loops.

We add 'systemd-mount' command instead of replace 'mount' command
based on the original mount.sh.

[YOCTO #12644]
Simply steps of reproduce:
Using systemd as init and an ext3 filesystem image,
boot core-image-minimal using:
  runqemu qemux86 slirp nographic qemuparams="-hda b.img"
  Note that hda is not mounted yet it can't be formatted either.

Detail steps of reproduce:
https://bugzilla.yoctoproject.org/show_bug.cgi?id=12644

Signed-off-by: Hongzhi.Song <hongzhi.s...@windriver.com>
---
 meta/recipes-core/udev/udev-extraconf/mount.sh | 60 ++++++++++++++++++++++----
 1 file changed, 51 insertions(+), 9 deletions(-)

diff --git a/meta/recipes-core/udev/udev-extraconf/mount.sh 
b/meta/recipes-core/udev/udev-extraconf/mount.sh
index d760328a09..5a877dd7ed 100644
--- a/meta/recipes-core/udev/udev-extraconf/mount.sh
+++ b/meta/recipes-core/udev/udev-extraconf/mount.sh
@@ -4,10 +4,26 @@
 #
 # Attempt to mount any added block devices and umount any removed devices
 
+BASE_INIT="`readlink -f "/sbin/init"`"
+INIT_SYSTEMD="/lib/systemd/systemd"
+
+if [ "x$BASE_INIT" = "x$INIT_SYSTEMD" ];then
+        MOUNT="/usr/bin/systemd-mount"
+        UMOUNT="/usr/bin/systemd-umount"
+
+        if [ ! -x $MOUNT ] && [ ! -x $UMOUNT ];
+        then
+                logger "/sbin/init is systemd but /usr/bin/systemd-[u]mount 
not found."
+                logger "Install systemd-[u]mount to be able to [un]mount all 
filesystems."
+                exit 0
+        fi
+else
+        MOUNT="/bin/mount"
+        UMOUNT="/bin/umount"
+fi
 
-MOUNT="/bin/mount"
 PMOUNT="/usr/bin/pmount"
-UMOUNT="/bin/umount"
+
 for line in `grep -h -v ^# /etc/udev/mount.blacklist 
/etc/udev/mount.blacklist.d/*`
 do
        if [ ` expr match "$DEVNAME" "$line" ` -gt 0 ];
@@ -17,7 +33,31 @@ do
        fi
 done
 
-automount() {  
+automount_systemd() {
+       name="`basename "$DEVNAME"`"
+
+        ! test -d "/run/media/$name" && mkdir -p "/run/media/$name"
+
+        # If filesystem type is vfat, change the ownership group to 'disk', and
+        # grant it with  w/r/x permissions.
+        case $ID_FS_TYPE in
+        vfat|fat)
+                MOUNT="$MOUNT -o umask=007,gid=`awk -F':' '/^disk/{print $3}' 
/etc/group`"
+                ;;
+        *)
+                ;;
+        esac
+
+        if ! $MOUNT -o silent --no-block -t auto $DEVNAME "/run/media/$name"
+        then
+                rm_dir "/run/media/$name"
+        else
+                logger "mount.sh: systemd-mount of [/run/media/$name] 
successful"
+                touch "/tmp/.automount-$name"
+        fi
+}
+
+automount() {
        name="`basename "$DEVNAME"`"
 
        ! test -d "/run/media/$name" && mkdir -p "/run/media/$name"
@@ -26,7 +66,7 @@ automount() {
        then
                MOUNT="$MOUNT -o silent"
        fi
-       
+
        # If filesystem type is vfat, change the ownership group to 'disk', and
        # grant it with  w/r/x permissions.
        case $ID_FS_TYPE in
@@ -47,7 +87,7 @@ automount() {
                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"
@@ -61,19 +101,21 @@ rm_dir() {
 # No ID_FS_TYPE for cdrom device, yet it should be mounted
 name="`basename "$DEVNAME"`"
 [ -e /sys/block/$name/device/media ] && media_type=`cat 
/sys/block/$name/device/media`
-
 if [ "$ACTION" = "add" ] && [ -n "$DEVNAME" ] && [ -n "$ID_FS_TYPE" -o 
"$media_type" = "cdrom" ]; 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 (note the root filesystem can show up as
        # /dev/root in /proc/mounts, so check the device number too)
        if expr $MAJOR "*" 256 + $MINOR != `stat -c %d /`; then
-               grep -q "^$DEVNAME " /proc/mounts || automount
+               if [ "`basename $MOUNT`" = "systemd-mount" ];then
+                       grep -q "^$DEVNAME " /proc/mounts || automount_systemd
+               else
+                       grep -q "^$DEVNAME " /proc/mounts || automount
+               fi
        fi
 fi
 
@@ -83,7 +125,7 @@ if [ "$ACTION" = "remove" ] || [ "$ACTION" = "change" ] && [ 
-x "$UMOUNT" ] && [
        do
                $UMOUNT $mnt
        done
-       
+
        # Remove empty directories from auto-mounter
        name="`basename "$DEVNAME"`"
        test -e "/tmp/.automount-$name" && rm_dir "/run/media/$name"
-- 
2.11.0

-- 
_______________________________________________
Openembedded-core mailing list
Openembedded-core@lists.openembedded.org
http://lists.openembedded.org/mailman/listinfo/openembedded-core

Reply via email to