I'm trying to build a simple "appliance"-type device running a minimal Linux and some custom code. Part of the functionality I am offering is that the user can attach a USB flash drive or hard drive to a specific USB port and the device can write data to a filesystem on that device.
This question has two parts:
#1: How can I determine the actual block device file for the USB mass storage device which has been attached to one specific hardware USB port?
Simply assuming that the USB storage device will always be at /dev/sdb
seems a bit risky, because suppose a user connects a hub to the port, or suppose you get a device with multiple endpoints (e.g. a card reader). Also, suppose the device reboots or starts up with a USB device in the USB port and for whatever reason the system decides to make the USB device /dev/sda
and the internal storage /dev/sdb
. (It is conceivable that the boot medium for this device will be USB as well, so that makes this quite likely.)
So what I basically want to be able to do is say "Give me the device file (like /dev/sdb) for the USB mass storage device at this specific USB port." If multiple block devices are found on one port, I would like an "array", or a list of all of the endpoints specific to that single device.
For the instance that someone attaches a hub to the port and connects multiple flash drives to that hub, I'd be ok with either 1) nothing showing up at all (and telling users that hubs are not allowed and they should only simply directly attach), or 2) getting a list of all block devices connected to the hub (similar to a multi-endpoint device).
Also obviously if someone attaches a non-storage device to that port, whatever method I come up should not give a storage device node.
#2: What is the best practice to mount a filesystem such so that it can be safely removed without first unmounting it as long as no writes are occurring?
Obviously users will be told to never remove the device while its light is flashing, etc. However, requiring a user to go through a manual unmount process could be a bad UX for this appliance. (It will have a very minimal UI, so implementing a safely-remove-hardware option that is easy to access and use would be challenging.) Basically, the user should be able to pull their drive out as soon as it is visually obvious that no more writing is occurring.
Obviously, most devices connected will be vfat. I'd like to also support ntfs (via ntfs-3g) and exfat (via exfat-fuse).
I could simply issue syncs whenever I write data in my own code, but one use case is an external app which streams data to the USB device in chunks. Think data logger. A file is created and data is streamed to it in chunks, but between each chunk it should be acceptable for the user to pull the drive when it is between writes, have the system detect it and cleanly stop data logging, and have the drive structure be safe.
Also once the device is pulled, I need to be aware of it quickly so my code can remove the mount and stop any operations that might be expecting to see the drive.
I know I'm asking a lot to allow users to just pull drives at will, and obviously if a user pulls a drive during a write this will be a problem, but I do want to allow at the very least the closest to this holy grail that I can.
Ideas?