# (e)udev rules for my HD hotswap cage/rack

## Zucca

I'm trying to figure out why my udev rules I brought from my old Arch installation won't work on my current Gentoo install. I'm running systemd on this machine and the rules should be the same.

```
ACTION=="remove", GOTO="end"

# First let's make sure we have the right controller

# pci0000:00/0000:00:11.0 is my sata controller address. You may have different.

# You may also have more than one controller! Like I have on my server motherboard.

# If you have, then you must add more rules. Easiest way is to create own rules for each SATA port.

# 

# To find the device path of a disk, run the following:

# udevadm info -q path -n /dev/<drive>

# Replace <drive> with any drive in any slot in the drive cage ie. sdb.

# Picking the first three sections should be enough to match a SATA controller.

# Just add asterix (*) at the end.

# Place yours in DEVPATH on next line.

ENV{DEVTYPE}=="disk", DEVPATH!="*/virtual/*", DEVPATH=="/devices/pci0000:00/0000:00:11.0/ata[1-9]*", IMPORT{builtin}="path_id"

# Note the 'ata[1-9]' on previous line does not always match to the port number.

# Why? I really don't know. But in my testing I have had ata8 on DEVPATH but

# the drive being on port 6. However, the just imported "path_id" contains the right number.

# My hotswap cage/rack has six slots and

# I have connected each slot to corresponding SATA port on my mother board.

# However on my motherboard the numbering starts from 0,

# while kernel starts numbering from 1.

# But this is actually convenient since my disk trays are numbered from 1 too.

# On next line we match SATA ports 1 to 6 and use a script to parse out the number only.

# The script is fairly simple and only prints consecutive numbers numbers from the end.

# You should also set those SATA ports as eSATA from BIOS/UEFI

ENV{DEVTYPE}=="disk", ENV{ID_PATH}=="*ata-[1-6]", PROGRAM="/etc/udev/id_path2num.sh $env{ID_PATH}", SYMLINK+="disk/DeLock-slot/SATA$result", SYMLINK+="disk/DeLock-slot/last_inserted"

# Finally we also create partition symlinks.

ENV{DEVTYPE}=="partition", ENV{ID_PATH}=="*ata-[1-6]*", PROGRAM="/etc/udev/id_path2num.sh $env{ID_PATH}", SYMLINK+="disk/DeLock-slot/SATA$result-part%n"

LABEL="end"

# Finally tell smartd to reload. Is this necessary?

#ENV{DEVTYPE}=="disk", RUN+="/sbin/killall -u root -s SIGHUP smartd"

```

... and there are the contents. I left my comments there intentionally, since those comments have some relevant information.

So far I've found the reason why these rules don't work: It's the part where I'm trying to import the PATH_ID: IMPORT{builtin}="path_id". Running "udevadm info -n /dev/<drive>" reveals all kinds of information BUT the required PATH_ID is missing.

So... To fix this I'd need a way to determine the SATA port number where the drive in question is connected to. When the ID_PATH had the information, the script (/etc/udev/id_path2num.sh) merely did a "grep -o" to to match the last digits since they always corresponded to the port number.

So. Has any of you made any similar setups? I had this because I gave those symlinks for smartd. When errors occur I could easily determine which drive to change and eject (hotswap even).

----------

## Zucca

Well... something happened. I'm not certain what exactly. But I think I had a package cleanup at some point and this happened. However, I have not updated systemd (version 232).

```
/dev/disk/DeLock-slot/last_inserted ==> /dev/sdf

/dev/disk/DeLock-slot/SATA1 ==> /dev/sda

/dev/disk/DeLock-slot/SATA1-part1 ==> /dev/sda1

/dev/disk/DeLock-slot/SATA1-part2 ==> /dev/sda2

/dev/disk/DeLock-slot/SATA1-part3 ==> /dev/sda3

/dev/disk/DeLock-slot/SATA2 ==> /dev/sdb

/dev/disk/DeLock-slot/SATA2-part1 ==> /dev/sdb1

/dev/disk/DeLock-slot/SATA2-part2 ==> /dev/sdb2

/dev/disk/DeLock-slot/SATA2-part3 ==> /dev/sdb3

/dev/disk/DeLock-slot/SATA3 ==> /dev/sdc

/dev/disk/DeLock-slot/SATA3-part1 ==> /dev/sdc1

/dev/disk/DeLock-slot/SATA3-part2 ==> /dev/sdc2

/dev/disk/DeLock-slot/SATA3-part3 ==> /dev/sdc3

/dev/disk/DeLock-slot/SATA4 ==> /dev/sdd

/dev/disk/DeLock-slot/SATA4-part1 ==> /dev/sdd1

/dev/disk/DeLock-slot/SATA4-part2 ==> /dev/sdd2

/dev/disk/DeLock-slot/SATA4-part3 ==> /dev/sdd3

/dev/disk/DeLock-slot/SATA5 ==> /dev/sde

/dev/disk/DeLock-slot/SATA5-part1 ==> /dev/sde1

/dev/disk/DeLock-slot/SATA5-part2 ==> /dev/sde2

/dev/disk/DeLock-slot/SATA5-part3 ==> /dev/sde3

/dev/disk/DeLock-slot/SATA6 ==> /dev/sdf

/dev/disk/DeLock-slot/SATA6-part1 ==> /dev/sdf1

/dev/disk/DeLock-slot/SATA6-part2 ==> /dev/sdf2

/dev/disk/DeLock-slot/SATA6-part3 ==> /dev/sdf3
```

... so now the rules work as they should. With this I can determine which of the disks are going bad (when they do) and know which to remove from the system.

Also one last note I made was that I don't have any udev installed (udev, eudev, mdev). It seems that systemd has engulfed udev (I don't know what to think about this. I just hope the devs can keep it stable.).

Anyway since the rules now work, I'll mark this as [SOLVED].

----------

## Zucca

I'm reopening this, since I cannot get this to work with eudev.

The culprit is the path_id built-in command.

It seems to fail on my sata drives:

```
udevadm --debug test-builtin path_id $(udevadm info --query=path --name=/dev/sdb)
```

... exits with non-zero code.

While querying my USB boot drive:

```
udevadm test-builtin path_id $(udevadm info --query=path --name=/dev/sdg)
```

... does work. The test outputs ID_PATH and ID_PATH_TAG values.

Does anyone else have this problem with SATA drives? Maybe I'm missing some kernel config option?

Is there a list for options one should enable in kernel to make all eudev functions work?

----------

