2

I generally get how the whole major/minor device number thing works for a given device (though please correct me if I'm way off here), and how a major device number essentially relates to a class of device (be that a block device or character device/character special), while the minor number relates to a specific type of devices under that. From this number, the kernel is able to ascertain what device driver it needs to use to interact with that device. At the file system level, the device number is stored within an inode stat struct, so when you stat a file as a user, it'll return the device ID as a 2 byte value, where the upper and lower bytes represent the major and minor numbers respectively. The stat struct has 2 members for specifying device IDs in this form - st_dev and st_rdev, where st_dev relates to the device which the respective file is on (in the case of an ordinary file on a storage device, st_dev would be the major/minor device for the partition the file is on).

However, if the file is a non-device mount, or a character special, or whatever, the major number in st_dev will be set to 0, the minor number will be set to something and instead, st_rdev may or may not be populated with the device type (depending whether the respective file system implements this). So my question is, what populates the minor device number in this instance, and how does it know what value to use / why does it use the value it does?

e.g.

stat /etc/passwd
=> Device: 801h, with no "Device Type" set -- This is expected major number 8 relates to SCSI devices, and the minor number of 1 relates to the first partition of this file (sda1)

stat /dev/sda1
=> Device: 6h, Device Type: 8,1 -- Here the Device (st_dev) has a major number of 0 (which is expected) and a minor number of 6 - why 6?

stat /dev/null -- Again, minor version of 6

stat /proc/version -- Minor version of 4

What am I missing?

I'm conscious of the fact that I'm referencing structs here, and this question may be better placed in stack overflow, but I feel like it's more a low level Linux question rather than explicitly a dev question - happy to relocate it though.

1 Answer 1

1

On my system, /proc is 6h, and /dev is 5h.

A quick test:

# for x in a b c d e f g h i j; do mkdir $x; mount -t tmpfs tmpfs $x; done
# stat */.

gave numbers 33h to 3dh with 35h missing from the middle (it was used by /run/user/1000/gvfs). Seems like just dynamic allocation with the first free number used at mount time.

Note that the numbers get reused, so at least in this case you can't reliably use st_dev to detect if the filesystem at a certain path changed.

2
  • Thanks, I didn't consider that they were just dynamically allocated at the time of mounting - I checked a couple of other mounts (like /sys, /dev/pts and /run, which had device numbers of 13h, 14h and 15h respectively, and I guess it makes sense that they'll have been mounted around the same time during boot). I'd erroneously assumed there was some secret, hard-coded value where /dev always had a value of 6h etc., but dynamic allocation would make much more sense (and explain why I didn't find much of use when searching for that specific minor device number!) Jul 6, 2020 at 15:40
  • @genericuser99, yep, the device numbers list doesn't say anything (not even that it's dynamic allocation): kernel.org/doc/Documentation/admin-guide/devices.txt
    – ilkkachu
    Jul 6, 2020 at 16:25

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.