Ubuntu USB Serial Devices – Udev Rule for Assigning Known Symlinks

serial portUbuntuudevusb

I have two (and possibly in the future, more) USB serial devices which are identical (down to the serial number, unfortunately) – they're actually BTC miners. Currently they end up as ttyUSBX where X is 0, 1 or 2, as there's another unrelated USB serial device as well (which need not be worried about here).

I would like to write a udev rule which will assign them predictable names within /dev, like /dev/miner0 where the zero is an incrementing integer. I don't care which of them ends up as which, but I do need them to be within a predictable range which won't change.

Currently I have this:

SUBSYSTEM=="tty", ATTRS{idVendor}=="10c4", ATTRS{idProduct}=="ea60", SYMLINK+="miner%n"

This is pretty close, as I end up with names like I want. The only problem is, since the miners and the third device can sometimes appear in a random order, I might end up with two of miner0, miner1 and miner2, but I never know which two (without manually looking). If I add any more non-miner usb serial devices (which is a possibility), it'll exacerbate the problem.

I had found reference to %e which looked like it did exactly what I wanted, but it doesn't seem to exist anymore.

How might I give these devices predictable names? I'd prefer not to tie them to their location on the USB bus as well if possible.


Further information/background

It's worth mentioning that I'm not that bothered what the names are, just that they be known and unchanging even if/when the device gets plugged into a different USB socket. I would simply forget the whole udev thing and use entries in /dev/serial/by-id, but as they have the same serial number, there's only one of them in there!

It's also worth mentioning that the reason for doing this is that the mining software needs to be told a list of devices to probe and find. I can just have it do all (it basically just finds all valid miners in the ttyUSB* range), but that annoys the non-miner device. So I need the names of the miners known ahead of time so I can configure it to use just those. Sadly it won't accept a wildcard (so just telling it to use /dev/miner* seems to be out of the question), hence this problem.

Best Answer

This is untested in combination:

Add a udev rule to IMPORT{program}="/usr/local/sbin/unique-num /run/miner-counter 0 MINER_NUM" for your miners.

Then you could use a simple shell script, something like this somewhat tested program:

#!/bin/sh

if [ $# -ne 3 ]; then
    echo "Usage: $0 data-file initial var-name" >&2
    exit 1
fi

datfile="$1"
lockfile="$1.lck"
initial=$2
key="$3"

(
    flock -x 9
    num=$initial
    if [ -e "$datfile" ]; then
        read -r num < "$datfile"
    fi

    next=`expr $num + 1`;
    echo $next > "$datfile"

    echo "$key=$num"
) 9> "$lockfile"

Then you can use that udev environment variable to name your miners.

Related Question