ZoL: “cannot resolve path” met zpool commandos

[English version below, this might be interesting for more than just the Dutch]

Voor een klant was ik vandaag bezig met het opzetten van een back-upserver op basis van ZFS. Een leuke machine, met 2 disken voor het OS en maar liefst 36 stuks voor de back-updata. De exacte inrichting is voor deze posting niet zo van belang, het gaat me meer om het probleem waar ik tegenaan liep.

zpool create home raidz1 scsi-350000393fb703ca6 scsi-350000393fb704160 scsi-350000393fb7041b9 scsi-350000393fb7042d6
cannot resolve path '/dev/disk/by-id/scsi-350000393fb704160-part1': 2

Om tot dan toe onverklaarbare reden geeft zpool bij een dergelijk commando soms deze error. Ik ben op zoek gegaan naar het waarom en of er omheen te werken was. Ik kwan uit op dit bugreport, waaruit blijkt dat Udev de boosdoener is. Udev gaat, op basis van systeemwijzigingen (die zpool uitvoert op het moment dat je een disk toe wilt voegen) de kernel daarvan op de hoogte stellen. Probleem is dus alleen dat Udev daar te lang over doet, en zpool voordat Udev klaar is al gaat klagen dat hij een disk niet kan vinden.

Ik heb er een workaround voor gevonden (geen oplossing dus!), waardoor ik toch verder kon gaan met het bouwen van m’n zpool.

  1. Open twee terminals naar de machine waar je mee bezig bent
  2. Draai: udevadm monitor in de ene terminal. Je krijgt nu de output te zien van waar Udev mee bezig is. Normaal gesproken is dat niets.
  3. Draai je zpool commando, bijvoorbeeld: zpool create foobar mirror disk1 disk2

Je ziet nu in de terminal waar udevadm monitor draait wat output verschijnen. Dat gaat over de disks waar zpool mee bezig is om ze te prepareren voor gebruik. Het zal je misschien opvallen (als je hier bent, is die kans vrij groot) dat zpool eerder stopt door de foutmelding dan udevadm stopt met output geven. En daar zit dus het probleem. Udev is nog bezig met het verwerken van de wijzigingen als zpool de betreffende disk al in gebruik wil nemen.

De workaround:

  1. Laat udevadm monitor draaien
  2. Draai in je andere terminal je zpool commando, en doe na een seconde of twee Control-Z om het zpool commando te pauzeren.
  3. Je krijgt je shell weer terug, en als het goed is zie je udevadm monitor nog even doorgaan met output geven. Als ie daarmee stopt, type je op je shell waar je zpool draaide fg zodat zpool weer verder gaat. Herhaal dit totdat je zpool zonder foutmeldingen ziet eindigen

Het is geen geweldige oplossing, maar het is minder vervelend dat zfs opnieuw moeten compileren met een andere timeoutwaarde voor udev, zoals in de bugreport genoemd wordt.

[English version]
I was setting up a backupserver for a customers today, based on ZFS. Some nice hardware, with 2 disks for the OS and no less than 36 disks for backupdata. The exact configuration of ZFS is not that interesting for this posting, it’s more about the issue I ran into.

zpool create home raidz1 scsi-350000393fb703ca6 scsi-350000393fb704160 scsi-350000393fb7041b9 scsi-350000393fb7042d6
cannot resolve path '/dev/disk/by-id/scsi-350000393fb704160-part1': 2

Up untill then it was unclear to my why zpool occasionally gave this error with such a command. I went looking for the cause of this error and if there was a way to work around it, and I ended up at this bugreport, which says that Udev is the cause. Udev will, based on changes in your hardwareconfiguration (which zpool causes the moment you try to add a disk) inform the kernel of these changes. The issue is that Udev is taking to long doing that. And since zpool tries to start using the disk before Udev is done notifying the kernel, zpool will complain that it cannot find the disk.

I’ve found a workaround for it (so NOT a permanent solution!), which enabled me to finish creating my zpool.

  1. Open two terminals to the machine your trying to configure
  2. Run: udevadm monitor in one terminal. You will start seeing output of what Udev is doing. Which is just about nothing, normally.
  3. Run your zpool command, e.g.: zpool create foobar mirror disk1 disk2

In the terminal where udevadm monitor is running, you should see some output. That output is about the disks that zpool is preparing for use. You should be able to notice (since you are reading this post, I expect you to at least) that zpool finishes with the error, before udevadm stops giving output. And there is your issue: Udev is still working on informing the kernel of the changes, while zpool wants to start using the disk.

The workaround:

  1. Keep udevadm monitor running
  2. In your other terminal, run your zpool command, and after about a second or two, press Control-Z to pause the zpool command.
  3. You will return to your shell. And you should see udevadm monitor continuing to print output. Once it stops doing that, run fg in the terminal where you were running zpool so zpool will continue to run. Repeat these steps until you see zpool exiting without errors.

Not a pretty workaround, but it’s less annoying than having to recompile ZFS with another value for the Udev-timeout, as suggested in the bugreport.