[OE-core] [PATCH v2] udev-extraconf: Add systemd-mount to udev-extraconf/mount.sh

Peter Kjellerstedt peter.kjellerstedt at axis.com
Fri Apr 13 15:32:56 UTC 2018


> -----Original Message-----
> From: openembedded-core-bounces at lists.openembedded.org
> [mailto:openembedded-core-bounces at lists.openembedded.org] On Behalf Of
> Hongzhi.Song
> Sent: den 12 april 2018 05:38
> To: openembedded-core at lists.openembedded.org
> Subject: [OE-core] [PATCH v2] udev-extraconf: Add systemd-mount to
> udev-extraconf/mount.sh
> 
> This patch fixs the problem that block devices unable to be formatted
> when
> systemd and udev-extraconf recipes added to rootfs.
> 
> If we add systemd and udev-extraconf recipes to rootfs:
>     VIRTUAL-RUNTIME_init_manager = "systemd"
>     DISTRO_FEATURES_append = " systemd"
>     DISTRO_FEATURES_BACKFILL_CONSIDERED += "sysvinit"
>     KERNEL_FEATURES_append = " cfg/systemd.scc"
>     IMAGE_INSTALL_append = " udev-extraconf"
>     IMAGE_FSTYPES += "tar.bz2 ext4"
>     IMAGE_INSTALL_append = " e2fsprogs-mke2fs"
> then systemd-udevd.service will invoke udev rules to automount block
> devices
> any probed under udevd's private namespace, this behavior results in
> host space
> can't format those devices. And host space can't find where the device
> is used.
> 
> Such as:
>     root at qemux86:~# mkfs.ext4 /dev/sda1
>     mke2fs 1.43.8 (1-Jan-2018)
>     /dev/sda1 contains a ext4 file system
>     last mounted on Tue Apr  3 06:22:41 2018
>     Proceed anyway? (y,N) y
>     /dev/sda1 is apparently in use by the system; will not make a
> filesystem here!
> 
> Command 'systemd-mount' recommended by systemd maintainer instead of
> command
> 'mount' will fix the problem brought with private namespace. Systemd-
> mount
> request the mount operation to be executed by PID 1, and hence host
> space can
> access the block devices.
> 
> [YOCTO #12644]
> 
> Signed-off-by: Hongzhi.Song <hongzhi.song at windriver.com>
> ---
>  meta/recipes-core/udev/udev-extraconf/mount.sh | 71
> ++++++++++++++++++++++----
>  1 file changed, 60 insertions(+), 11 deletions(-)
> 
> diff --git a/meta/recipes-core/udev/udev-extraconf/mount.sh
> b/meta/recipes-core/udev/udev-extraconf/mount.sh
> index d760328a09..4ba9f1dd99 100644
> --- a/meta/recipes-core/udev/udev-extraconf/mount.sh
> +++ b/meta/recipes-core/udev/udev-extraconf/mount.sh
> @@ -4,10 +4,28 @@
>  #
>  # Attempt to mount any added block devices and umount any removed
> devices
> 
> +BASE_INIT="`readlink "/sbin/init"`"
> +INIT_SYSTEMD="/lib/systemd/systemd"

In a system where ${base_libdir} != "lib", e.g, if usrmerge is in 
DISTRO_FEATURES, this may not match reality. You should replace 
all hardcoded paths with something like @base_libdir@ and then 
use sed to apply all the relevant bitbake path variables.

> +
> +if [ "x$BASE_INIT" = "x$INIT_SYSTEMD" ];then
> +	# systemd as init uses systemd-mount to mount block devices

You should use tabs to indent this function to match the rest of 
this file.

> +    MOUNT="/usr/bin/systemd-mount"
> +    UMOUNT="/usr/bin/systemd-umount"
> +
> +    if [ -x $MOUNT ] && [ -x $UMOUNT ];
> +    then
> +        logger "Using systemd-mount to finish mount"
> +    else
> +        logger "Linux init is using systemd, so please install systemd-mount to finish mount"
> +        exit 1
> +    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 +35,35 @@ do
>  	fi
>  done
> 
> -automount() {
> +automount_systemd() {
> +    name="`basename "$DEVNAME"`"
> +
> +    ! test -d "/run/media/$name" && mkdir -p "/run/media/$name"

The above is better written as:

    [ -d "/run/media/$name" ] || mkdir -p "/run/media/$name"

> +
> +    MOUNT="$MOUNT -o silent"
> +
> +    # If filesystemtype 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`"
> +        ;;
> +    # TODO
> +    *)
> +        ;;
> +    esac
> +
> +    if ! $MOUNT --no-block -t auto $DEVNAME "/run/media/$name"
> +    then
> +        #logger "mount.sh/automount" "$MOUNT -t auto $DEVNAME \"/run/media/$name\" failed!"
> +        rm_dir "/run/media/$name"
> +    else
> +        logger "mount.sh/automount" "Auto-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 +72,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
> @@ -46,7 +92,7 @@ automount() {
>  		logger "mount.sh/automount" "Auto-mount of [/run/media/$name] successful"
>  		touch "/tmp/.automount-$name"
>  	fi
> -}
> +

You should not remove that "}" or the script will become invalid...

> 
>  rm_dir() {
>  	# We do not want to rm -r populated directories
> @@ -68,22 +114,25 @@ if [ "$ACTION" = "add" ] && [ -n "$DEVNAME" ] && [ -n "$ID_FS_TYPE" -o "$media_t
>  	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
> -	fi

Use tabs to indent the code below.

> +    if expr $MAJOR "*" 256 + $MINOR != `stat -c %d /`; then
> +        if [ "`basename $MOUNT`" = "systemd-mount" ];then
> +            grep -q "^$DEVNAME " /proc/mounts || automount_systemd
> +        else
> +            grep -q "^$DEVNAME " /proc/mounts || automount
> +        fi
> +    fi
>  fi
> 
> -
>  if [ "$ACTION" = "remove" ] || [ "$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"`"
>  	test -e "/tmp/.automount-$name" && rm_dir "/run/media/$name"
> --
> 2.13.3

//Peter




More information about the Openembedded-core mailing list