3

I have a scenario that is not answered by other questions about getting the parent device from the partition device.

Imagine that udev is being used to populate /dev instead of the kernel, and that some wacky rules are dictating how these files are populated. The literal path for a partition block device is /dev/partition while the path for its parent is the literal /dev/parent. All the other questions rely on symlinks in /sys to get the parent block device of a partition block device, but the pathnames in /sys are NOT guaranteed to match the names of the corresponding device nodes in /dev. So, the question is: programmatically, how can one get /dev/parent from /dev/partition?

2
  • Bit of a historic perspective: "instead of the kernel": The kernel is populating /dev through udev. The alternative is either devtmpfs (which is the kernel directly populating /dev) or just a directory with statically made device nodes (the way it was before udev, where the kernel had no way of actually populating the /dev directory itself. Commented 2 days ago
  • but problem is: with "wacky rules" we can't even take a guess. This depends 100% on your rules! No general statement can be made. You might be able to go through sysfs, but if you don't have devtmpfs, it's not inherent that this will work. Commented 2 days ago

3 Answers 3

4

On Linux, with lsblk, you can get the parent kernel name with lsblk -o pkname:

$ ls -ld foo
brw-rw---- 1 root disk 8, 6 Apr 17 06:54 foo
$ lsblk -no pkname foo
sda
$ lsblk -no name foo
sda6

AFAICT, it's only documented in the output of lsblk -H aka --list-columns:

$ lsblk -H | grep -i parent
      PKNAME <string>        internal parent kernel device name

With zsh:

$ zmodload zsh/stat
$ stat -A d +rdev foo &&
    print -r -- /sys/dev/block/$(( d >> 8 )):$(( d & 0xff ))(:P:h:t)
sda

Where we do it by hand by extracting the major:minor from the rdev field of the stat structure, locate the device in /sys via the /sys/dev/block/major:minor symlink (assuming it's a block device in the first place), then use modifiers in glob qualifiers, to get its real Path, then the head (dirname, so parent) of that path (assuming it is a partition in the first place), then the tail (basename).

1
  • oh, that I didn't know! Commented yesterday
3

The answer is still to go through sysfs. The names are whatever, you can have a udev rule to create a /dev/jabberwocky if you like.

However as long as it's a kernel block device, then it will still have a major:minor number and you can go by that identifier to query the devices identity through sysfs.

$ ls -l /dev/jabberwocky
brw-rw---- 1 root disk 259, 139 Apr 16 08:34 /dev/jabberwocky
$ stat -L /dev/jabberwocky # alternatively
[…] Device type: 259,139 […]
$ find /sys -name 259:139
/sys/dev/block/259:139
$ stat /sys/dev/block/259:139
File: /sys/dev/block/259:139 -> ../../devices/pci0000:00/0000:00:02.1/0000:02:00.0/usb1/1-1/1-1:1.0/host6/target6:0:0/6:0:0:0/
block/sdc/sdc42

And so on.

It's more complicated when userspace is somehow involved (filesystem in userspace, network block device, and the like). Basically sysfs will provide the info only if the kernel itself knows.

2

It's literally udev's job to present these things in a way that is useful to userland. So fix your "wacky rules" to actually additionally give you the device you need!

If you can't infer that from the major/minors of the block devices set up by udev, there's little chance that the pseudofiles /sys/block/*/dev and /sys/block/*/*p[0–9]/dev contain useful major:minor that allow you to look that up in /dev by going through all block devices and checking their major:minor against that.

The only alternative I see is going to /sys/block, and doing something like

for devicelink in */device; do
  printf 'master device %s: %s\n' "${devicelink}" "$(readlink -m "${devicelink}")"
done

to get a list of master devices, and then explore that to infer a hierarchy.

You must log in to answer this question.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.