I'd like to have a backup script execute when certain external USB drives get mounted. I'm trying to achieve this with udev.
What I've done so far:
Identified my USB drive using sudo udevadm info --attribute-walk --name /dev/sda
, the output of which is:
looking at device '/devices/pci0000:00/0000:00:14.0/usb1/1-5/1-5.2/1-5.2.3/1-5.2.3:1.0/host0/target0:0:0/0:0:0:0/block/sda':
KERNEL=="sda"
SUBSYSTEM=="block"
DRIVER==""
ATTR{size}=="1953525168"
ATTR{events_async}==""
ATTR{ext_range}=="256"
ATTR{range}=="16"
ATTR{inflight}==" 0 0"
ATTR{hidden}=="0"
ATTR{ro}=="0"
ATTR{discard_alignment}=="0"
ATTR{alignment_offset}=="0"
ATTR{capability}=="50"
ATTR{events_poll_msecs}=="-1"
ATTR{removable}=="0"
ATTR{events}==""
ATTR{stat}==" 445 7963 19565 3971 7 1 64 21 0 1036 3204 0 0 0 0"
looking at parent device '/devices/pci0000:00/0000:00:14.0/usb1/1-5/1-5.2/1-5.2.3/1-5.2.3:1.0/host0/target0:0:0/0:0:0:0':
KERNELS=="0:0:0:0"
SUBSYSTEMS=="scsi"
DRIVERS=="sd"
ATTRS{state}=="running"
ATTRS{inquiry}==""
ATTRS{evt_inquiry_change_reported}=="0"
ATTRS{evt_capacity_change_reported}=="0"
ATTRS{device_busy}=="0"
ATTRS{evt_mode_parameter_change_reported}=="0"
ATTRS{evt_lun_change_reported}=="0"
ATTRS{ioerr_cnt}=="0xc"
ATTRS{iocounterbits}=="32"
ATTRS{eh_timeout}=="10"
ATTRS{vendor}=="ST310005"
ATTRS{queue_depth}=="1"
ATTRS{device_blocked}=="0"
ATTRS{blacklist}==""
ATTRS{evt_media_change}=="0"
ATTRS{scsi_level}=="3"
ATTRS{evt_soft_threshold_reached}=="0"
ATTRS{iodone_cnt}=="0x1f8"
ATTRS{queue_type}=="none"
ATTRS{timeout}=="30"
ATTRS{model}=="20AS "
ATTRS{max_sectors}=="240"
ATTRS{iorequest_cnt}=="0x1f8"
ATTRS{type}=="0"
ATTRS{rev}==" "
ATTRS{dh_state}=="detached"
looking at parent device '/devices/pci0000:00/0000:00:14.0/usb1/1-5/1-5.2/1-5.2.3/1-5.2.3:1.0/host0/target0:0:0':
KERNELS=="target0:0:0"
SUBSYSTEMS=="scsi"
DRIVERS==""
looking at parent device '/devices/pci0000:00/0000:00:14.0/usb1/1-5/1-5.2/1-5.2.3/1-5.2.3:1.0/host0':
KERNELS=="host0"
SUBSYSTEMS=="scsi"
DRIVERS==""
looking at parent device '/devices/pci0000:00/0000:00:14.0/usb1/1-5/1-5.2/1-5.2.3/1-5.2.3:1.0':
KERNELS=="1-5.2.3:1.0"
SUBSYSTEMS=="usb"
DRIVERS=="usb-storage"
ATTRS{bNumEndpoints}=="02"
ATTRS{supports_autosuspend}=="1"
ATTRS{bInterfaceNumber}=="00"
ATTRS{bInterfaceClass}=="08"
ATTRS{interface}=="MSC Bulk-Only Transfer"
ATTRS{bInterfaceProtocol}=="50"
ATTRS{authorized}=="1"
ATTRS{bAlternateSetting}==" 0"
ATTRS{bInterfaceSubClass}=="06"
looking at parent device '/devices/pci0000:00/0000:00:14.0/usb1/1-5/1-5.2/1-5.2.3':
KERNELS=="1-5.2.3"
SUBSYSTEMS=="usb"
DRIVERS=="usb"
ATTRS{maxchild}=="0"
ATTRS{bNumConfigurations}=="1"
ATTRS{authorized}=="1"
ATTRS{tx_lanes}=="1"
ATTRS{manufacturer}=="Lomega"
ATTRS{serial}=="50F26FFFFFFF"
ATTRS{bDeviceSubClass}=="00"
ATTRS{bConfigurationValue}=="1"
ATTRS{devpath}=="5.2.3"
ATTRS{bmAttributes}=="c0"
ATTRS{configuration}=="USB Mass Storage"
ATTRS{quirks}=="0x0"
ATTRS{ltm_capable}=="no"
ATTRS{busnum}=="1"
ATTRS{urbnum}=="1569"
ATTRS{removable}=="unknown"
ATTRS{bcdDevice}=="0000"
ATTRS{speed}=="480"
ATTRS{idProduct}=="0370"
ATTRS{bDeviceProtocol}=="00"
ATTRS{rx_lanes}=="1"
ATTRS{bDeviceClass}=="00"
ATTRS{bNumInterfaces}==" 1"
ATTRS{avoid_reset_quirk}=="0"
ATTRS{bMaxPacketSize0}=="64"
ATTRS{product}=="External HD"
ATTRS{devnum}=="19"
ATTRS{idVendor}=="059b"
ATTRS{version}==" 2.00"
ATTRS{bMaxPower}=="2mA"
looking at parent device '/devices/pci0000:00/0000:00:14.0/usb1/1-5/1-5.2':
KERNELS=="1-5.2"
SUBSYSTEMS=="usb"
DRIVERS=="usb"
ATTRS{bConfigurationValue}=="1"
ATTRS{bNumConfigurations}=="1"
ATTRS{tx_lanes}=="1"
ATTRS{bmAttributes}=="e0"
ATTRS{urbnum}=="200"
ATTRS{bMaxPacketSize0}=="64"
ATTRS{quirks}=="0x0"
ATTRS{manufacturer}=="VIA Labs, Inc. "
ATTRS{avoid_reset_quirk}=="0"
ATTRS{rx_lanes}=="1"
ATTRS{devnum}=="6"
ATTRS{configuration}==""
ATTRS{bDeviceClass}=="09"
ATTRS{busnum}=="1"
ATTRS{version}==" 2.10"
ATTRS{speed}=="480"
ATTRS{idVendor}=="17ef"
ATTRS{authorized}=="1"
ATTRS{bDeviceSubClass}=="00"
ATTRS{bMaxPower}=="0mA"
ATTRS{bDeviceProtocol}=="02"
ATTRS{bNumInterfaces}==" 1"
ATTRS{maxchild}=="4"
ATTRS{bcdDevice}=="0a74"
ATTRS{removable}=="unknown"
ATTRS{devpath}=="5.2"
ATTRS{idProduct}=="3071"
ATTRS{product}=="USB2.0 Hub "
ATTRS{ltm_capable}=="no"
looking at parent device '/devices/pci0000:00/0000:00:14.0/usb1/1-5':
KERNELS=="1-5"
SUBSYSTEMS=="usb"
DRIVERS=="usb"
ATTRS{product}=="USB2.0 Hub "
ATTRS{devnum}=="3"
ATTRS{rx_lanes}=="1"
ATTRS{avoid_reset_quirk}=="0"
ATTRS{bmAttributes}=="e0"
ATTRS{devpath}=="5"
ATTRS{speed}=="480"
ATTRS{bDeviceClass}=="09"
ATTRS{idProduct}=="3071"
ATTRS{removable}=="removable"
ATTRS{bConfigurationValue}=="1"
ATTRS{bcdDevice}=="0a73"
ATTRS{quirks}=="0x0"
ATTRS{bNumConfigurations}=="1"
ATTRS{busnum}=="1"
ATTRS{bMaxPower}=="0mA"
ATTRS{configuration}==""
ATTRS{tx_lanes}=="1"
ATTRS{idVendor}=="17ef"
ATTRS{authorized}=="1"
ATTRS{manufacturer}=="VIA Labs, Inc. "
ATTRS{ltm_capable}=="no"
ATTRS{urbnum}=="52"
ATTRS{bDeviceProtocol}=="02"
ATTRS{bNumInterfaces}==" 1"
ATTRS{maxchild}=="5"
ATTRS{version}==" 2.10"
ATTRS{bDeviceSubClass}=="00"
ATTRS{bMaxPacketSize0}=="64"
looking at parent device '/devices/pci0000:00/0000:00:14.0/usb1':
KERNELS=="usb1"
SUBSYSTEMS=="usb"
DRIVERS=="usb"
ATTRS{version}==" 2.00"
ATTRS{tx_lanes}=="1"
ATTRS{bMaxPacketSize0}=="64"
ATTRS{bConfigurationValue}=="1"
ATTRS{busnum}=="1"
ATTRS{bcdDevice}=="0500"
ATTRS{ltm_capable}=="no"
ATTRS{bNumInterfaces}==" 1"
ATTRS{serial}=="0000:00:14.0"
ATTRS{configuration}==""
ATTRS{devpath}=="0"
ATTRS{idProduct}=="0002"
ATTRS{devnum}=="1"
ATTRS{bNumConfigurations}=="1"
ATTRS{bDeviceSubClass}=="00"
ATTRS{bmAttributes}=="e0"
ATTRS{bMaxPower}=="0mA"
ATTRS{product}=="xHCI Host Controller"
ATTRS{speed}=="480"
ATTRS{avoid_reset_quirk}=="0"
ATTRS{maxchild}=="12"
ATTRS{authorized}=="1"
ATTRS{urbnum}=="92"
ATTRS{idVendor}=="1d6b"
ATTRS{bDeviceProtocol}=="01"
ATTRS{quirks}=="0x0"
ATTRS{bDeviceClass}=="09"
ATTRS{manufacturer}=="Linux 5.0.0-15-generic xhci-hcd"
ATTRS{interface_authorized_default}=="1"
ATTRS{authorized_default}=="1"
ATTRS{rx_lanes}=="1"
ATTRS{removable}=="unknown"
looking at parent device '/devices/pci0000:00/0000:00:14.0':
KERNELS=="0000:00:14.0"
SUBSYSTEMS=="pci"
DRIVERS=="xhci_hcd"
ATTRS{revision}=="0x30"
ATTRS{d3cold_allowed}=="1"
ATTRS{enable}=="1"
ATTRS{ari_enabled}=="0"
ATTRS{broken_parity_status}=="0"
ATTRS{subsystem_device}=="0x2279"
ATTRS{local_cpulist}=="0-7"
ATTRS{irq}=="127"
ATTRS{vendor}=="0x8086"
ATTRS{msi_bus}=="1"
ATTRS{device}=="0x9ded"
ATTRS{dbc}=="disabled"
ATTRS{local_cpus}=="ff"
ATTRS{consistent_dma_mask_bits}=="64"
ATTRS{numa_node}=="-1"
ATTRS{dma_mask_bits}=="64"
ATTRS{class}=="0x0c0330"
ATTRS{subsystem_vendor}=="0x17aa"
ATTRS{driver_override}=="(null)"
looking at parent device '/devices/pci0000:00':
KERNELS=="pci0000:00"
SUBSYSTEMS==""
DRIVERS==""
Based on this info, I created a file in /etc.udev/rules.d/10.autobackup.rules
with:
SUBSYSTEM=="block", ACTION=="add", ATTRS{serial}=="50F26FFFFFFF", RUN+="/usr/bin/touch ~david/test_udev.txt"
After reloading the rules with sudo udevadm control --reload
and running udevadm test /block/sda
I get:
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.
Load module index
Parsed configuration file /usr/lib/systemd/network/99-default.link
Created link configuration context.
Reading rules file: /etc/udev/rules.d/10.autobackup.rules
Reading rules file: /usr/lib/udev/rules.d/39-usbmuxd.rules
Reading rules file: /usr/lib/udev/rules.d/40-usb_modeswitch.rules
Reading rules file: /usr/lib/udev/rules.d/40-vm-hotadd.rules
Reading rules file: /usr/lib/udev/rules.d/50-apport.rules
Reading rules file: /usr/lib/udev/rules.d/50-firmware.rules
Reading rules file: /usr/lib/udev/rules.d/50-udev-default.rules
Reading rules file: /usr/lib/udev/rules.d/55-dm.rules
Reading rules file: /usr/lib/udev/rules.d/55-ippusbxd.rules
Reading rules file: /usr/lib/udev/rules.d/56-hpmud.rules
Reading rules file: /usr/lib/udev/rules.d/60-block.rules
Reading rules file: /usr/lib/udev/rules.d/60-cdrom_id.rules
Reading rules file: /usr/lib/udev/rules.d/60-crda.rules
Reading rules file: /usr/lib/udev/rules.d/60-drm.rules
Reading rules file: /usr/lib/udev/rules.d/60-evdev.rules
Reading rules file: /usr/lib/udev/rules.d/60-input-id.rules
Reading rules file: /usr/lib/udev/rules.d/60-inputattach.rules
Reading rules file: /usr/lib/udev/rules.d/60-libfprint0.rules
Reading rules file: /usr/lib/udev/rules.d/60-libgphoto2-6.rules
Reading rules file: /usr/lib/udev/rules.d/60-libsane.rules
Reading rules file: /usr/lib/udev/rules.d/60-pcmcia.rules
Reading rules file: /usr/lib/udev/rules.d/60-persistent-alsa.rules
Reading rules file: /usr/lib/udev/rules.d/60-persistent-input.rules
Reading rules file: /usr/lib/udev/rules.d/60-persistent-storage-dm.rules
Reading rules file: /usr/lib/udev/rules.d/60-persistent-storage-tape.rules
Reading rules file: /usr/lib/udev/rules.d/60-persistent-storage.rules
Reading rules file: /usr/lib/udev/rules.d/60-persistent-v4l.rules
Reading rules file: /usr/lib/udev/rules.d/60-sensor.rules
Reading rules file: /usr/lib/udev/rules.d/60-serial.rules
Reading rules file: /usr/lib/udev/rules.d/61-gdm.rules
Reading rules file: /usr/lib/udev/rules.d/61-gnome-settings-daemon-rfkill.rules
Reading rules file: /usr/lib/udev/rules.d/61-persistent-storage-android.rules
Reading rules file: /usr/lib/udev/rules.d/64-btrfs.rules
Reading rules file: /usr/lib/udev/rules.d/64-xorg-xkb.rules
Reading rules file: /usr/lib/udev/rules.d/65-libwacom.rules
Reading rules file: /usr/lib/udev/rules.d/66-snapd-autoimport.rules
Reading rules file: /usr/lib/udev/rules.d/69-cd-sensors.rules
Reading rules file: /usr/lib/udev/rules.d/69-libmtp.rules
Reading rules file: /usr/lib/udev/rules.d/69-wacom.rules
Reading rules file: /usr/lib/udev/rules.d/70-joystick.rules
Reading rules file: /usr/lib/udev/rules.d/70-mouse.rules
Reading rules file: /usr/lib/udev/rules.d/70-power-switch.rules
Reading rules file: /usr/lib/udev/rules.d/70-printers.rules
Reading rules file: /etc/udev/rules.d/70-snap.core.rules
Reading rules file: /usr/lib/udev/rules.d/70-spice-vdagentd.rules
Reading rules file: /usr/lib/udev/rules.d/70-touchpad.rules
Reading rules file: /usr/lib/udev/rules.d/70-u2f.rules
Reading rules file: /usr/lib/udev/rules.d/70-uaccess.rules
Reading rules file: /usr/lib/udev/rules.d/71-power-switch-proliant.rules
Reading rules file: /usr/lib/udev/rules.d/71-seat.rules
Reading rules file: /usr/lib/udev/rules.d/71-u-d-c-gpu-detection.rules
Reading rules file: /usr/lib/udev/rules.d/73-seat-late.rules
Reading rules file: /usr/lib/udev/rules.d/73-special-net-names.rules
Reading rules file: /usr/lib/udev/rules.d/73-usb-net-by-mac.rules
Reading rules file: /usr/lib/udev/rules.d/75-net-description.rules
Reading rules file: /usr/lib/udev/rules.d/75-probe_mtd.rules
Reading rules file: /usr/lib/udev/rules.d/77-mm-cinterion-port-types.rules
Reading rules file: /usr/lib/udev/rules.d/77-mm-dell-port-types.rules
Reading rules file: /usr/lib/udev/rules.d/77-mm-ericsson-mbm.rules
Reading rules file: /usr/lib/udev/rules.d/77-mm-fibocom-port-types.rules
Reading rules file: /usr/lib/udev/rules.d/77-mm-haier-port-types.rules
Reading rules file: /usr/lib/udev/rules.d/77-mm-huawei-net-port-types.rules
Reading rules file: /usr/lib/udev/rules.d/77-mm-longcheer-port-types.rules
Reading rules file: /usr/lib/udev/rules.d/77-mm-mtk-port-types.rules
Reading rules file: /usr/lib/udev/rules.d/77-mm-nokia-port-types.rules
Reading rules file: /usr/lib/udev/rules.d/77-mm-pcmcia-device-blacklist.rules
Reading rules file: /usr/lib/udev/rules.d/77-mm-qdl-device-blacklist.rules
Reading rules file: /usr/lib/udev/rules.d/77-mm-sierra.rules
Reading rules file: /usr/lib/udev/rules.d/77-mm-simtech-port-types.rules
Reading rules file: /usr/lib/udev/rules.d/77-mm-telit-port-types.rules
Reading rules file: /usr/lib/udev/rules.d/77-mm-ublox-port-types.rules
Reading rules file: /usr/lib/udev/rules.d/77-mm-usb-device-blacklist.rules
Reading rules file: /usr/lib/udev/rules.d/77-mm-usb-serial-adapters-greylist.rules
Reading rules file: /usr/lib/udev/rules.d/77-mm-x22x-port-types.rules
Reading rules file: /usr/lib/udev/rules.d/77-mm-zte-port-types.rules
Reading rules file: /usr/lib/udev/rules.d/78-graphics-card.rules
Reading rules file: /usr/lib/udev/rules.d/78-sound-card.rules
Reading rules file: /usr/lib/udev/rules.d/80-debian-compat.rules
Reading rules file: /usr/lib/udev/rules.d/80-drivers.rules
Reading rules file: /usr/lib/udev/rules.d/80-ifupdown.rules
Reading rules file: /usr/lib/udev/rules.d/80-iio-sensor-proxy.rules
Reading rules file: /usr/lib/udev/rules.d/80-libinput-device-groups.rules
Reading rules file: /usr/lib/udev/rules.d/80-mm-candidate.rules
Reading rules file: /usr/lib/udev/rules.d/80-net-setup-link.rules
Reading rules file: /usr/lib/udev/rules.d/80-udisks2.rules
Reading rules file: /usr/lib/udev/rules.d/84-nm-drivers.rules
Reading rules file: /usr/lib/udev/rules.d/85-brltty.rules
Reading rules file: /usr/lib/udev/rules.d/85-hdparm.rules
Reading rules file: /usr/lib/udev/rules.d/85-hplj10xx.rules
Reading rules file: /usr/lib/udev/rules.d/85-nm-unmanaged.rules
Reading rules file: /usr/lib/udev/rules.d/85-regulatory.rules
Reading rules file: /usr/lib/udev/rules.d/89-alsa-ucm.rules
Reading rules file: /usr/lib/udev/rules.d/90-alsa-restore.rules
Reading rules file: /usr/lib/udev/rules.d/90-bolt.rules
Reading rules file: /usr/lib/udev/rules.d/90-console-setup.rules
Reading rules file: /usr/lib/udev/rules.d/90-fwupd-devices.rules
Reading rules file: /usr/lib/udev/rules.d/90-libinput-model-quirks.rules
Reading rules file: /usr/lib/udev/rules.d/90-nm-thunderbolt.rules
Reading rules file: /usr/lib/udev/rules.d/90-pulseaudio.rules
Reading rules file: /usr/lib/udev/rules.d/95-cd-devices.rules
Reading rules file: /usr/lib/udev/rules.d/95-dm-notify.rules
Reading rules file: /usr/lib/udev/rules.d/95-upower-csr.rules
Reading rules file: /usr/lib/udev/rules.d/95-upower-hid.rules
Reading rules file: /usr/lib/udev/rules.d/95-upower-wup.rules
Reading rules file: /usr/lib/udev/rules.d/97-hid2hci.rules
Reading rules file: /usr/lib/udev/rules.d/99-systemd.rules
Rules contain 393216 bytes tokens (32768 * 12 bytes), 38404 bytes strings
31877 strings (265263 bytes), 28376 de-duplicated (230361 bytes), 3502 trie nodes used
Invalid inotify descriptor.
Starting 'ata_id --export /dev/sda'
Process 'ata_id --export /dev/sda' failed with exit code 1.
sda: Failed to create symlink '/dev/disk/by-id/usb-ST310005_20AS_50F26FFFFFFF-0:0.tmp-b8:0' to '../../sda': Permission denied
DEVPATH=/devices/pci0000:00/0000:00:14.0/usb1/1-5/1-5.2/1-5.2.3/1-5.2.3:1.0/host0/target0:0:0/0:0:0:0/block/sda
DEVNAME=/dev/sda
DEVTYPE=disk
MAJOR=8
MINOR=0
ACTION=add
SUBSYSTEM=block
ID_VENDOR=ST310005
ID_VENDOR_ENC=ST310005
ID_VENDOR_ID=059b
ID_MODEL=20AS
ID_MODEL_ENC=20AS\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20
ID_MODEL_ID=0370
ID_REVISION=0000
ID_SERIAL=ST310005_20AS_50F26FFFFFFF-0:0
ID_SERIAL_SHORT=50F26FFFFFFF
ID_TYPE=disk
ID_INSTANCE=0:0
ID_BUS=usb
ID_USB_INTERFACES=:080650:
ID_USB_INTERFACE_NUM=00
ID_USB_DRIVER=usb-storage
DEVLINKS=/dev/disk/by-path/pci-0000:00:14.0-usb-0:5.2.3:1.0-scsi-0:0:0:0 /dev/disk/by-id/usb-ST310005_20AS_50F26FFFFFFF-0:0
ID_PATH=pci-0000:00:14.0-usb-0:5.2.3:1.0-scsi-0:0:0:0
ID_PATH_TAG=pci-0000_00_14_0-usb-0_5_2_3_1_0-scsi-0_0_0_0
TAGS=:systemd:
USEC_INITIALIZED=3351039864
run: '/usr/bin/unshare -m /usr/bin/snap auto-import --mount=/dev/sda'
run: '/usr/bin/touch ~david/test_udev.txt'
run: '/lib/udev/hdparm'
Unload module index
Unloaded link configuration context.
Which appears to indicate that the touch
command in my script should be executed when the USB drive gets added (and after mounting the drive, which is a constraint I will need when performing the backup). Yet, next time I add the drive (turning it off then on), no file gets created at ~david/test_udev.txt
.
Executing sudo udevadm trigger
doesn't get the file to be created either.
The end goal is for a backup command to execute, but at this time I'm just trying to touch a file to get the basics working...
udevadm trigger
by default does achange
action. Your rule isadd
. Useudevadm monitor
to show what happens when you turn the HDD on and off. You also should use a wrapper script for doing things: https://askubuntu.com/questions/25071/how-to-run-a-script-when-a-specific-flash-drive-is-mounted – Thomas May 19 '19 at 14:14~david/test_udev.txt
a typo! – George Udosen May 19 '19 at 14:55~David
exist? – George Udosen May 19 '19 at 15:05~david
exists. I'm not sure why you're asking if the filename is a typo: it isn't, but do you think it might be causing issues? Note that I've also tried to use systemd to trigger the backup: https://askubuntu.com/questions/1144587/systemd-user-service-not-starting-on-login – David Sulc May 19 '19 at 19:35~David
should be~/David
! So you shouldn't expect that backup to occur if the location doesn't exist! – George Udosen May 19 '19 at 19:39/home/david
which has~david
as a shorthand.~/david
would resolve to/home/joe/david
(assuming the current user isjoe
). – David Sulc May 20 '19 at 17:02