Why do USB flash drives show up as rotating?

I’m creating up a udev rule for setting the scheduler, and using ATTR{queue/rotational} to distinguish between rotating and non-rotating devices. (mq-deadline for SSDs and bfq for rotating drives)
For some odd reason, all external USB flash drives set the ‘rotational’ value as true. (tested in F35)

$ cat /sys/block/sdd/queue/rotational 
1

My internal SATA SSD shows the correct state’

cat /sys/block/sdc/queue/rotational 
0

Is there some reason that this is the case? Is there a way to fix this?

1 Like

Hi @vk2bea Answers on https://unix.stackexchange.com/questions/439109/set-usb-flash-drive-as-non-rotational-drive

2 Likes

Yes, that’s the problem.

All my flash drives give the wrong value using hdparm
Nominal Media Rotation Rate: 5980

… edit. oops, wrong drive. There is no line with Nominal Media Rotation Rate: for the flash drive.

Just a guess here as I have not seen that issue explicitly.

Flash drives that are usb connected use udev for config and activation. There is a line of things there involved. USB, udev, the device itself, and it seems difficult to pinpoint at which level the current config occurs. I reviewed the link above and it is possible that the fix in the last post on that thread may solve it for you. That post seems to point at udev as the issue.

EDIT:
In fact when you brought this up I found the same on my system and then added the udev rule in that linked post and the next time I connected the same flash drive it now shows what it should.

# cat /sys/block/sdf/queue/rotational
0

Yes the rule sets all removable sd drives as non rotating. This is not always true.

Understood, and possibly true for some devices.

I have both flash drive and HDD in external enclosure and the HDD is configured as rotational when plugged in with the flash drive configured as non-rotational.

When plugging them in at different times the flash drive is identified as /dev/sdX, and the HDD is also identified as /dev/sdX so your blanket statement that all external sd drives will be marked as non-rotating is not 100% correct.

The udev rule looks for the term that will identify it as rotational and if present does not change the designation.

The udev rule in the stack exchange example, skips if the device is non-rotational. The flash drive and the rotating drive both show as rotating and thus will have rotating set to 0.
There is a rule looking at queue_type but, at least from my external hdd, it is “none” and thus will be set to non-rotating by the rule.

I think you are reading the rule wrong.

It sets most devices as rotating with a 1 by default.
If already marked as non rotating it skips. (0)
if it has the attr “queue_type != none” it skips (probably rotating)
otherwise if it is removable, block & usb then it flips it to non rotating (0)

In the udev logic 1 means rotating, 0 means non-rotating.
This is not to say the rule is perfect, but at least for what I have right now it works.

No, I did know that.
For both external flash drives and external spinning drives ‘rotating’ is 1.
As I noted the external spinning drive has a queue type of none, so the line attrs “queue_type != none” will not jump over the rule that sets it no non-rotating.

I checked my HDD and noted it did not even show a queue_type so it would fit the rule and skip. I then also checked and since this is the drive I use for backups I remembered that it is mounted according to the fstab entry I created.

I expect someone could device a more universal rule that would fit all or most external spinning devices, but for now it works for me.

1 Like

Have a look in /sys/block/sdd/device/, maybe you’ll see it there.
Notice that the rule is actually attrs not attr so that it checks for the attribute anywhere up the device tree.

$ udevadm info -a -n /dev/sdd |grep queue_type
    ATTRS{queue_type}=="none"

With that info I looked again at my removable HDD and find it does have that attribute as you posted. However the next line looks for ATTR{removable}=="1" and mine is ATTR{removable}=="0" so even though everything else fits it fails the last test and so remains marked as rotational as expected.