From Fedora Project Wiki

There are several things in Linux that make dealing with block devices much stranger than one would hope. Here's the ones I can think of quickly:

Depending on which subsystem is implementing a block device, there are several differences in the way block devices and their partitions are manifest:

  • device node numbering

There are several schemes for numbering device nodes

  • major number with assigned minors (sda is 8:0, sda1 is 8:1 , sdb is 8:16 ) This means you're limited to 15 partitions on scsi devices, and 63 for "ide" when not using libata.
  • major number is in /proc/devices, minor numbers are assigned at device creation
  • ioctl() calls

The kernel's internal partitioning scheme is managed with some IOCTLs, such as BLKRRPART, BLKPG/BLKPG_ADD_PARTITION, and BLKPG/BLKPG_DEL_PARTITION, which only work on some devices. They work on hd* (ide without libata), sd* (scsi), md_d* (partitionable md), but not on md (non-partitionable md) or device-mapper devices (i.e. multipath or dmraid)

  • device node naming

There are several schemes for naming devices. These aren't just userland, they're also the related to the names in e.g. /sys/block/ (${driver} below is not necessarily the name of the driver, but rather an identifying tag it uses)

  • (cciss, sx8, etc.):
/dev /dev/${driver}/c${controller}d${drivenumber}[p${partnumber}]
/sys /sys/block/${driver}!c${controller}d${drivenumber}[/${driver}!c${controller}d${drivenumber}p${partnumber}]
  • (sd, hd):
/dev /dev/${driver}${diskletter}[${partnumber}]
/sys /sys/block/${driver}${driveletter}[/${driver}${driveletter}${partnumber}]
  • md (no partitions):
/dev /dev/md${mdnumber}
/sys /sys/block/md${mdnumber}
  • mdp (partitionable md):
/dev /dev/md_d${mdpnumber}[p${partnumber}]
/sys /sys/block/md_d${mdpnumber}[/md_d${mdpnumber}p${partnumber}]
  • lvm (no partitions, dm device):
/dev all of:
/dev/dm-${dmnumber} (a real block device node}
/dev/mapper/${volgroupname}-${logvolname} (a real block device node)
/dev/${volgroupname}/${logvolname} (a symlink into /dev/mapper)
/sys /sys/block/dm-${dmnumber}
  • dmraid and mpath (partitioned dm device):

both the main device and the partitions are device-mapper rules; the partitions don't show up in /proc/partitions, etc.

/dev all of:
/dev/dm-${dmnumber} (a real block device node)
/dev/${arbitrary name}[${arbitrary part delimiter}${arbitrary part specifier, usually an integer}] (usually a real block device node for a dm object)
/sys /sys/block/dm-${dmnumber}
  • loopback devices:
/dev /dev/loop${loopnumber} (just the loopback device)
/dev /dev/loop${loopnumber}${arbitrary part delimiter}${arbitrary part specifier} (partition, via device-mapper, created by e.g. kpartx)
/sys /sys/block/loop${loopnumber}
/sys /sys/dm-${dmnumber} (for a partition)
  • sysfs wackiness

sysfs has /sys/block/$device/{holders,slaves} directories to represent which devices depend on which others. If a device uses the kernel's partitioning, these don't reflect the device<->partition relationship.

  • hotplug wackiness

When a device is added, you get a bunch of hotplug events. The last one for a particular block device has SUBSYSTEM="block", and is basically the "this device is ready" event. SCSI devices (including SATA and PATA with libata) have a files /sys/block/$device/{device,model}. These don't get probed until after the hotplug event. Also, UUIDs/serial numbers/etc aren't probed at all.

  • probing of md/mdp devices

two weird things here:

  • to activate an md or mdp device, you have to mknod it first, then use mdadm on the created node.
  • mdp's _partitions_ show up the normal ways (i.e. uevents to notify userland)
  • md0 always exists (i.e. there's always a /sys/block/md0), even before you activate any devices.

I'm sure there's more here that sucks.