/path/to/directory/ is a path that points within an encrypted volume, to an arbitrary depth. In a bash script I need to determine if the block device related to this path is a removable device. I'm using Arch Linux.

I have looked at a lot of similar questions (such as these listed below and others) but did not find a suitable answer:

This is an example of what I'm working with:

findmnt -n -o SOURCE --target /path/to/directory/

findmnt -D --target /path/to/directory
SOURCE                         FSTYPE  SIZE   USED AVAIL USE% TARGET
/dev/mapper/luksdev[/@subvolume] btrfs   4.5T 203.5G  4.3T   4% /path/to/directory

df -P /path/to/directory/ | awk 'END{print $1}'

(The findmnt parameter --target seems to be required if the path is not the exact mountpoint.)

If the script can determine the block device (e.g., /dev/sda1) associated with /dev/mapper/luksdev, I get a step closer:

udevadm info --query=all --name=/dev/sda1 | grep ID_BUS | grep "=usb"
E: ID_BUS=usb

But I assume not all removable devices are usb, right?

By the way, I am OK with methods specific to BTRFS, if that makes this any easier. I did check:

btrfs - Find physical block device of root filesystem on an encrypted filesystem? - Unix & Linux Stack Exchange

EDIT: based on answer by Vojtech Trefny, here is what I have:

mapper_path=$(findmnt -n -o SOURCE --target /path/to/directory/ | cut -d [ -f 1)
mydev=$(lsblk -sl -o NAME /${mapper_path} | tail -n 1)
drive_name=$(udisksctl info -b /dev/${mydev} | grep "Drive:" | cut -d"'" -f2)
drive_name=$(echo $drive_name | sed -e 's|/org/freedesktop/UDisks2/drives/||')
udisksctl info -d ${drive_name} | grep "\sRemovable:" | cut -d":" -f2 | tr -d "[:blank:]"

From the /dev/mapper path, the easiest way to get the disk name should be lsblk with -s to list devices in inverse order:

$ lsblk -sl -o NAME /dev/mapper/<name> | tail -1

Easiest way from here is probably to check removable property from sysfs

$ cat /sys/block/sda/removable

but I'd recommend using UDisks here, it does some extra checks on top of the sysfs information so I assume sysfs can be wrong about some removable devices. You can either use busctl to communicate with UDisks over DBus or udisksctl and grep from the output.

$ busctl get-property org.freedesktop.UDisks2 /org/freedesktop/UDisks2/block_devices/sda org.freedesktop.UDisks2.Block Drive 
o "/org/freedesktop/UDisks2/drives/<drive_name>"

$ busctl get-property org.freedesktop.UDisks2 /org/freedesktop/UDisks2/drives/<drive_name> org.freedesktop.UDisks2.Drive Removable 
b false


$ udisksctl info -b /dev/sda | grep "Drive:" | cut -d"'" -f2

$ udisksctl info -d <drive_name> | grep "\sRemovable:" | cut -d":" -f2 | tr -d "[:blank:]"
  • Very helpful. Thank you. Unfortunately, when using either busctl or udisksctl I get the error Error looking up object for drive /org/freedesktop/UDisks2/drives/SanDisk_Cruzer_Blade_XYZ123456789. If I use /sys/block/sdX/removable it does give the expected value of 1 for USB sticks, but for a removable USB HDD (WD Elements) it reports 0. – MountainX Oct 10 '20 at 7:20
  • 1
    @MountainX that's because it's not removable. You can't the platter and change it with another ;-) What you're asking for is impossible. You can only make "educated" guesses (USB -> "removable", etc). – user414777 Oct 10 '20 at 7:31
  • @MountainX realpath /sys/block/sda will tell you the full path to the device. Starting from there, you can make some guesses. – user414777 Oct 10 '20 at 7:41
  • @MountainX Is the drive visible in udisksctl dump? If the sda object says the drive is /org/freedesktop/UDisks2/drives/SanDisk_Cruzer_Blade_XYZ123456789 and then the drive object is not there, that's a bug in UDisks, unfortunately. – Vojtech Trefny Oct 10 '20 at 7:47
  • 1
    @VojtechTrefny: I figured the issue out, and accepted your answer. See edit in my question for details. – MountainX Oct 10 '20 at 8:14

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.