8

On most Linux systems udev usually creates symlinks in

/dev/disk/by-uuid/
/dev/disk/by-path/

which point to actual device nodes (/dev/sda, /dev/sdb, etc).

I don't have udev on my system, and I would like to generate these symlinks manually. I know I can use blkid to generate the by-uuid name.

But how can I generate the by-path name for a given disk (e.g. /dev/sda1) without using udev?

Specifically, I am looking for a way to find which of my disks is the disk connected via iSCSI from host 10.1.14.22. It could be sdb, or sdc or perhaps other, since I am connected to several (different) iSCSI hosts at the same time.

  • 1
    They are /dev/disk/by-id, /dev/disk/by-path, and /dev/disk/by-uuid. They are not /dev/disk-by-uuid and /dev/disk-by-path. – v7d8dpo4 Apr 25 '16 at 3:55
  • The source for generating the path id is in src/udev/udev-builtin-path_id.c in the source of systemd. You can translate it into shell script. – v7d8dpo4 Apr 25 '16 at 8:25
  • 1
    Do you have a working sysfs? For me, realpath /sys/block/sdd/device/scsi_device gives a plausible-looking value of /sys/devices/pci0000:00/0000:00:1a.7/usb1/1-3/1-3:1.0/host12/target12:0:0/12:0:0:0/scsi_device, which looks like it needs only a little massaging to get the corresponding name (/dev/disk/by-path/pci-0000:00:1a.7-usb-0:3:1.0-scsi-0:0:0:0 in this case). – Toby Speight Apr 28 '16 at 16:44
  • So here's a question. Where do the UUIDs come from? I always assumed this was some identifying string embedded inside the drives themselves. – Faheem Mitha Apr 28 '16 at 18:07
  • @Toby Speight - yes, I do have working /sys. But however I massage realpath, it does not show the IP address of the iISCSI host. – Martin Vegter Apr 29 '16 at 6:35
1

This script would do the trick, at least for most typical scenarios. It requires on blkid, lsscsi and sed:

#!/bin/bash
mkdir -p /dev/disk/by-{path,uuid}
for dev in `blkid -o device | grep -v block`; do
  ln -s "$dev" "/dev/disk/by-uuid/$(blkid -o value -s UUID "$dev")"
done

lsscsi -v | sed 'N;s/\n//' |\
  sed 's/.*\(\/dev\/\w\+\).*\(pci\)[0-9]\{4\}[^/]\+\/[^/]\+\/\([0-9:.]\+\)[^ ]*\/\([0-9:]\+\)[]].*/\1 \2-\3-scsi-\4/' |\
  sed 's/.*\(\/dev\/\w\+\).*\(pci\)[^/]*\/\([0-9:.]\+\)\/ata[^ ]*\/\([0-9:]\+\)[]].*/\1 \2-\3-ata-\4/' |\
  while read dev pci; do
    pp="/dev/disk/by-path/$pci"
    ln -s "$dev" "$pp"
    for part in "${dev}"[0-9]*; do
      [ -e "$part" ] && ln -s "$part $pp-part${part/$dev/}"
    done
  done
  • @TobySpeight blkid -o device lists all /dev/* and /dev/block/* devices. /dev/block/* are likely produced by udev, so in Martin's system should not be a problem. Thanks for that, I'm updating the script with your solution which is more elegant. – Ziggy Crueltyfree Zeitgeister Apr 29 '16 at 8:28
  • My code tests that blkid -s UUID isn't empty - not all my block devices have UUIDs, and I didn't want to end up with /dev/disk/by-uuid/sdd1 etc. I also use ln -r to get results exactly like udev's, but I expect that isn't important. – Toby Speight Apr 29 '16 at 12:00
  • My blkid -o device doesn't give me any /dev/block/* - not sure what's different there... – Toby Speight Apr 29 '16 at 12:06

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.