0

I have a system with multiple USBs connected. I would like to find a USB that contains a specific .ini file or is empty (in which case I want to create the .ini file) and mount it at /media/mount_point. If no such USB exists then nothing should be mounted.

I have tried creating a udev rule which runs the following script for each USB:

#!/bin/sh

LOGFILE="/home/user/mount.log"
MOUNTDIRECTORY="/media/mount_point"

if [ -z "$DEVNAME" ]; then
  exit
fi

echo "USB device detected at $DEVNAME" >> $LOGFILE

if grep '$MOUNTDIRECTORY ' /proc/mounts; then
  # Already mounted
  echo "Mount directory already in use" >> $LOGFILE
  exit
fi

mount $DEVNAME $MOUNTDIRECTORY -o umask=0000,gid=1000,uid=1000 &>> $LOGFILE

if [ $? -eq 0 ]; then
    echo "$DEVNAME mounted at $MOUNTDIRECTORY" >> $LOGFILE
    if [ -f $MOUNTDIRECTORY/log.ini ]; then
        echo "Log.ini found. Ready to log" >> $LOGFILE
        break
    elif [ -z "$(ls -A $MOUNTDIRECTORY)" ]; then
        echo "USB device empty. Creating log.ini" >> $LOGFILE
        touch $MOUNTDIRECTORY/log.ini
        break
    else
        umount $MOUNTDIRECTORY
    fi
else
    echo "Failed to mount $DEVNAME at $MOUNTDIRECTORY" >> $LOGFILE
fi

echo "" >> $LOGFILE

This works if the .ini exists (after editing systemd-udevd.service per this question), but not if an empty USB is found. The $LOGFILE output reports that an .ini has been created, but if I check then there is no .ini file on the mounted device. If I unmount, I find the .ini file has been created at the mount point instead.

Why does the .ini file end up at the mount point rather than on the mounted USB? How can I fix this?

Alternatively, is there a better approach than udev for this problem?

1 Answer 1

0

I have been able to find a satisfactory solution.

Rather than attempt to mount from udev directly, I instead spawned a new service as suggested in this question. Ultimately I ended up with this udev rule:

ACTION=="add",<Your device specifiers here>,ENV{SYSTEMD_WANTS}="log@$env{DEVPATH}.service"

Added the following service to /etc/systemd/system:

[Service]
Type=oneshot
TimeoutStartSec=300
GuessMainPID=false
RemainAfterExit=yes
ExecStart=/bin/bash -c "/home/user/mount.sh %I"

And modified my script to:

#!/bin/sh

LOGFILE="/home/user/mount.log"
MOUNTDIRECTORY="/media/mount_point"
DEVPATH=$1
BASENAME="$(basename $DEVPATH)"
DEVICE="/dev/$BASENAME"

if [ -z "$BASENAME" ]; then
  exit
fi

echo "" >> $LOGFILE
echo "New USB device detected at $DEVICE" >> $LOGFILE

if grep '$MOUNTDIRECTORY ' /proc/mounts; then
  # Already mounted
  echo "Mount directory already in use" >> $LOGFILE
  exit
fi

mount $DEVICE $MOUNTDIRECTORY -o umask=0000,gid=1000,uid=1000 >> $LOGFILE

if [ $? -eq 0 ]; then
    echo "$DEVICE mounted at $MOUNTDIRECTORY" >> $LOGFILE
    if [ -f $MOUNTDIRECTORY/log.ini ]; then
        echo "Log.ini found. Ready to log" >> $LOGFILE
        break
    elif [ -z "$(ls -A $MOUNTDIRECTORY)" ]; then
        echo "USB device empty. Creating log.ini" >> $LOGFILE
        touch $MOUNTDIRECTORY/log.ini
        break
    else
        echo "Log.ini not found. Unmounting" >> $LOGFILE
        umount $MOUNTDIRECTORY
    fi
else
    echo "Failed to mount $DEVICE at $MOUNTDIRECTORY" >> $LOGFILE
fi

echo "" >> $LOGFILE

I still don't understand the cause of my original issue (log.ini file appearing at the mount point rather than one the mounted device). If anyone has an explanation I would be interested.

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .