04 January 2024

Changing a zpool from ashift=9 to ashift=12

I wanted the additional write speed on my nas drives that come from aligning the ashift value with physical sector size of my hard drives (ashift=9 is 512 bytes and ashift=12 is 4KB). Unfortunately, you cannot change ashift on an existing zpool, so you will have to backup the data, destroy the pool, recreate it, and then restore the data.


Prereq

  • pv (to monitor the process/speed)
    • sudo apt-get install pv
  • encrypted zfs data with the "wrong" ashift value that you want to migrate

Process to move

  1. Stop any process that writes to your storage that you want to move
  2. Setup temporary storage location
    • sudo zpool create external-storage mirror /dev/disk/by-id/ata-WDC_WD30EFRX-68EUZN0_WD-XXXXXXX /dev/disk/by-id/ata-WDC_WD30EFRX-68EUZN0_WD-XXXXXXX
    • sudo zfs create -o encryption=aes-256-gcm -o keylocation=prompt -o keyformat=passphrase external-storage/encrypted
  3. Create a snapshot
    • sudo zfs snapshot storage/encrypted@migrate-20231229
    • sudo zfs list -t snapshot
  4. Copy snapshot over
    • sudo bash -c 'zfs send storage/encrypted@migrate-20231229 | pv | zfs recv external-storage/encrypted/backup'
  5. Ensure that all files have been backed up
  6. Unmount the datasets
    • sudo zfs unmount storage/encrypted
  7. Destroy the old zpool
    • sudo zpool destroy storage
  8. Create the new zpool
    • sudo zpool create storage mirror /dev/disk/by-id/ata-WDC_WD60EFZX-68B3FN0_WD-XXXXXXX ata-WDC_WD60EFZX-68B3FN0_WD-XXXXXXX
  9. Ensure is setup with the correct ashift value
    • sudo zdb -C storage | grep ashift
  10. Create a temporary file to contain your passphrase because since zfs recv is using stdin to pull in the data it cannot prompt for it
    • echo "super-secret" > /home/example/passphrase.txt
  11. Copy snapshot back
    • sudo bash -c 'zfs send external-storage/encrypted/backup@migrate-20231229 | pv | zfs recv -o encryption=aes-256-gcm -o keylocation=file:///home/example/passphrase.txt -o keyformat=passphrase storage/encrypted'
  12. Change from a file to prompt for password
    • sudo zfs change-key -o keylocation=prompt storage/encrypted
  13. Remove the temp passphrase
    • rm /home/example/passphrase.txt
  14. Check that all your files are back in place
  15. Now if you want you can destroy the backup or export it and keep the backup
    • sudo zpool destroy external-storage
    • OR
    • sudo zpool export external-storage

Appendix

If you see an error like:

  • cannot receive new filesystem stream: zfs receive -F cannot be used to destroy an encrypted filesystem or overwrite an unencrypted one with an encrypted one
  • That means that you cannot copy to the encrypted dataset. What I did to get around this was to instead copy to a child of the encrypted dataset.

Sources:

No comments:

Post a Comment