Udev rule mount usb drive automatically - nutthawit/alpine-dotfile GitHub Wiki
In this tutorial, we will configure eudev to automatically mount the USB drive to /mnt/btr_backup whenever it is plugged in.
Install eudev
apk add eudev eudev-doc
Start by write the simple script for udev that triggers a custom event
udevstands for Userspace Device Management.udevis now integrated intosystemd, whileeudevis a fork ofudevcreated primarily to decouple it fromsystemd.
Create file on /usr/local/bin/simple-script
touch /usr/local/bin/simple-script && chmod +x /usr/local/bin/simple-script
vi /usr/local/bin/simple-script
Add following content:
#!/bin/ash
/bin/date >> /tmp/udev.log
Save and test the script
trigger.sh
cat /tmp/udev.log
Tue Oct 31 01:05:28 NZDT 2035
Next step is to make udev trigger the script
Install eudev by the setup script
apk add alpine-conf
setup-devd udev
# add eudev man pages
apk add eudev-doc
Read more on https://wiki.alpinelinux.org/wiki/Eudev#Setup_script
With the udevadm monitor command, you can tap into udev in real time and see what it sees when you plug in different devices
udevadm monitor
The monitor function prints received events for:
- UDEV: the event udev sends out after rule processing
- KERNEL: the kernel uevent
You will notice that the type of event is an add event.
If you don't know where your thumb drive is plugged in, you can use this command:
dmesg | tail | grep -i sd*
If that command returned sda: sda1, for instance, you know the kernel has assigned you thumb drive the sdb label.
Or you can use lsblk command.
Now you can view udev information about the device using:
udevadm info -a -n /dev/sda | less
The udevadm info process reports on a device (specified by the device path), then "walks" up the chain of parent devices.
looking at device '/devices/pci0000:00/0000:00:14.0/usb1/1-2/1-2:1.0/host2/target2:0:0/2:0:0:0/block/sda':
KERNEL=="sda"
SUBSYSTEM=="block"
DRIVER==""
ATTR{ext_range}=="256"
ATTR{range}=="16"
ATTR{partscan}=="1"
ATTR{alignment_offset}=="0"
ATTR{diskseq}=="26"
ATTR{ro}=="0"
Device hierarchy
The Linux kernel actually represents devices in a tree-like structure, and this information is exposed through sysfs and useful when writing rules. For example, the device representation of my hard disk device is a child of the SCSI disk device, which is in turn a child of the Serial ATA controller device, which is in turn a child of the PCI bus device. It is likely that you will find yourself needing to refer to information from a parent of the device in question, for example the serial number of my hard disk device is not exposed at the device level, it is exposed by its direct parent at the SCSI disk level
Your job is to pick out parts of udev's report about a device that are most unique to that device, then tell udev to trigger your script when those unique attributes are detected.
Now create a custom udev rule to trigger simple-script
vi /etc/udev/rules.d/10-local.rules
Files in /etc/udev/rules.d/ are parsed in lexical order, and in some circumstances, the order in which rules are parsed is important. In general, you want your own rules to be parsed before the defaults, so I suggest you create a file at /etc/udev/rules.d/10-local.rules and write all your rules into this file.
Add following content:
SUBSYSTEM=="block", ACTION=="add", RUN+="/usr/local/bin/simple-script"
Save the file and run test using udevadm test /dev/sda. Your output should look like this:
calling: test
version 3.2.14
This program is for debugging only, it does not run any program
specified by a RUN key. It may show incorrect results, because
some values may be different, or not available at a simulation run.
does not exist, please run udevadm hwdb --update
Load module index
timestamp of '/etc/udev/rules.d' changed
Reading rules file: /etc/udev/rules.d/10-local.rules
Reading rules file: /usr/lib/udev/rules.d/50-udev-default.rules
Reading rules file: /usr/lib/udev/rules.d/60-autosuspend.rules
Reading rules file: /usr/lib/udev/rules.d/60-block.rules
Counting backward from the end of the output to line 4, you will see that your rule is being read without error.
If you encounter an error, the output will look like this:
invalid key/value pair in file /etc/udev/rules.d/10-local.rules on line 1, starting at character 59 (',')
This occurred because I removed the double quotation mark (") at the end of the line.
SUBSYSTEM=="block", ATTRS{idVendor}=="0951", ACTION=="add", RUN+="/usr/local/bin/simple-script
Now unplug your thumb drive, and reboot a Linux machine.
Theoretically, you can just issue
udevadm control --reload, which should load all rules, but at this stage in the game, it's best to eliminate all variables. Udev is complex enough, and you don't want to be lying in bed all night wondering if that rule didn't work because of a syntax error or if you just should have rebooted. So reboot regardless of what your POSIX pride tells you.
When your system is back online, plug in your thumb drive and run following command:
cat /tmp/udev.log
Tue Oct 31 01:35:28 NZDT 2035
If you see a very recent date and time returned from /tmp/udev.log, udev has successfully triggered your script.
Since the KERNEL label of sdb can change depending upon how many other drives were plugged in before you plugged that thumb drive in, that's not the optimal parent attribute for a udev rule.
For more specific, we can use Device - Product Vendor ID. Run following command:
lsusb
Bus 001 Device 001: ID 1d6b:0002 Linux 6.12.49-0-lts xhci-hcd xHCI Host Controller
Bus 001 Device 003: ID 13d3:5a11 Azurewave USB2.0 VGA UVC WebCam
Bus 001 Device 004: ID 13d3:3529 Realtek Bluetooth Radio
Bus 002 Device 001: ID 1d6b:0003 Linux 6.12.49-0-lts xhci-hcd xHCI Host Controller
Bus 001 Device 002: ID 0bda:0129 Generic USB2.0-CRW
Bus 001 Device 007: ID 0951:1666 Kingston DataTraveler 3.0
In this example, the 0951:1666 before Kingston DataTraveler 3.0. denotes the idVendor and idProduct attributes.
Now you can now include these attributes in your rule.
SUBSYSTEM=="block", ATTRS{idVendor}=="0951", ACTION=="add", RUN+="/usr/local/bin/simple-script"
The
ATTRS{idVendor}is a parent attribute (retrieved by:udevadm info -a -n /dev/sda | less). If an attribute used to specify your device is not exposed at the device level, you can also use it from its parent level.
Test this (yes, you should still reboot, just to make sure you're getting fresh reactions from udev), and it should work the same as before.
This tutorial is inspried by this article, with added information relevant to Alpine Linux.
References: