PVE Tinkering Notes (3) Creating ZFS on the Hard Disk Originally Used in QNAP
QNAP switching to ZFS? The self-healing function is quite handy, but dealing with Linux compatibility issues is a real hassle. LVM remnants causing disk wipe failure? Each kernel object needs to be removed one by one. Choosing wrong parameters during pool creation? That can truly lead to endless trouble.
目录18 个章节
Introduction
After some research, I decided to use ZFS as the file system for the two mechanical hard drives. I could have used ext4 just like QNAP does, but ZFS is safer — it has self-healing capabilities and can handle bit-flip issues. In short, it's just better to use.
If you're looking for flexibility, you can use Btrfs. There's a great write-up on this topic that you can refer to: Data Disk Partitioning: Btrfs File System - Building a NAS/Small Server from Scratch
In one sentence: ZFS is not just a file system — it is an intelligent storage solution.
ZFS (Zettabyte File System) is an open-source, advanced file system and logical volume manager originally developed by Sun Microsystems.
Unlike traditional file systems (such as ext4, NTFS), ZFS combines file system + RAID + volume management all in one.
Key features: self-repair, snapshots, high reliability, large-capacity support.
Check Hard Disk
Mainly uses the two commands fdisk -l and lsblk.
fdisk -l: View disk partition information (lower-level, raw)lsblk: View disk block device tree structure (more intuitive, human-oriented)
Command Explanation:
🧱 fdisk -l
-
Full name is "list partition table"
-
Displays all disks and their partition information, capacity, file system type (MBR/GPT), etc.
-
Requires root privileges (so it is commonly used as
sudo fdisk -l) -
Example output:
pgsql复制编辑Disk /dev/sda: 512 GB Device Boot Start End Sectors Size Type /dev/sda1 * 2048 999423 997376 487M EFI System /dev/sda2 999424 976773119 975773696 465G Linux filesystem -
📌 More "low-level," helpful for understanding the disk partition table structure.
🌳 lsblk
-
Full name is "list block devices"
-
Displays all block devices (disks, partitions, LVM, RAID, etc.) and their mount status
-
Presents in a tree-like structure, which is more intuitive
-
Does not display loop devices with empty mount points (unless additional parameters are added)
-
Does not require root privileges by default
-
Example output:
pgsql复制编辑NAME MAJ:MIN RM SIZE RO TYPE MOUNTPOINT sda 8:0 0 512G 0 disk ├─sda1 8:1 0 487M 0 part /boot/efi └─sda2 8:2 0 511.5G 0 part / -
📌 More suitable for quickly identifying which device is mounted to which directory. For example, when you connect a new SSD, it will appear with a name like
/dev/sdXor/dev/nvmeXn1.
Backup Data
Refer to my previous content
There are several methods:
- rsync:
rsync -a --info=progress2 /mnt/disk1/your-folder /mnt/disk2/ - Midnight Commander (mc) (Visual)
I recommend using mc. Note that if you are operating on a server via SSH, be sure to use a tool like screen to start a background session to prevent the connection from dropping halfway through the copy.
After the backup is complete, please verify the data yourself. You can also refer to my previous article for the method.
Format Hard Disk
The simplest way is to use the Wipe Disk feature in PVE.
Error
However, I encountered an error during usage: disk/partition '/dev/sda1' has a holder
Analyzing the cause, "holder" indicates that there are still kernel objects using this partition.
Common Holders
| Device Type | Check Command | Typical Reason for Old Disks in QNAP |
|---|---|---|
| LVM PV → dm-? | pvs, lsblk -o NAME,TYPE | QTS typically rolls the entire disk into vg1/lv1 |
| mdraid → md127 | mdadm --detail --scan | QTS might have created a soft RAID cache area |
| dm-crypt / luks | lsblk -f | If encryption sharing was enabled |
| Mount Point | `mount | grep sda1` |
As long as holders exist, Proxmox's wipe_disk script (essentially sgdisk --zap-all + wipefs -a) will be blocked from writing by the kernel, resulting in a 500 error.
Troubleshooting Method
lsblk -f
ls /sys/block/sda/sda1/holders
Output like dm-0 dm-1 → indicates it is occupied by LVM/MD, etc.
Solution
⚠️ Please verify the disk name for all commands (using /dev/sda as an example here). Incorrect operations will immediately destroy data!
| Step | Command | Description |
|---|---|---|
| 1️⃣ Unmount mount point | umount -f /dev/sda? 2>/dev/null | Ensure the partition is not in use. |
| 2️⃣ Disable LVM | vgchange -an vg1 lvremove -f /dev/vg1/lv1 pvremove /dev/sda1 | Use pvs, vgs to check actual vg/lv names. |
| 3️⃣ Stop mdraid | mdadm --stop /dev/md127 mdadm --zero-superblock /dev/sda1 | Only if lsblk shows md* devices. |
| 4️⃣ Final signature wipe | sgdisk --zap-all /dev/sda wipefs -a /dev/sda | Equivalent to PVE's "Wipe Disk" function. |
After completing the steps, run ls /sys/block/sda/sda1/holders —— the directory should be empty.
Then, returning to the Web UI and clicking Wipe Disk should no longer result in an error.
Creating ZFS
In the Web UI, select the node (mine is called PVE) - Disks - ZFS - Create ZFS
TL;DR: Choose the disk, fill in the name, select single disk for RAID level (you can choose Mirror if you want redundancy), select lz4 for compression, and set ashift to 12
For those who want to delve deeper, please refer to the following explanation.
Recommended Configuration
RAID Level: Choose based on trade-offs between capacity, performance, fault tolerance, and rebuild speed (mirror/raid10 favors performance and small-scale setups, raidzN favors capacity and simplicity, draidN favors capacity and fast self-healing).
Compression Algorithm: For general use, select lz4 (or on); for maximum compression, consider zstd or gzip.
ashift: For modern disks, choose 12.
What Do These Parameters Mean?
RAID Level (Pool Layout)
| Type | Minimum Disks | Fault Tolerance | Characteristics & Use Cases |
|---|---|---|---|
| mirror | ≥2 | 1 disk (within each mirror group) | Mirrors data completely to another disk; slightly better read performance, write performance similar to a single disk; recommended for small-scale deployments sensitive to both performance and reliability. |
| raid10 | ≥4 | At least 1 disk (per mirror group) | Mirrors in pairs first, then stripes across groups; balances read/write performance and fault tolerance, suitable for high-IOPS scenarios. |
| raidz1 (Proxmox UI calls it "RAIDZ") | ≥3 | 1 disk (single parity) | Single parity disk; higher space utilization than mirror but impacts performance during resilvering; suitable for capacity-first scenarios less sensitive to rebuild time. |
| raidz2 | ≥4 | 2 disks (double parity) | Double parity, tolerates two simultaneous disk failures; one more parity disk than raidz1, suitable for medium-to-large capacity pools with higher reliability requirements. |
| raidz3 | ≥5 | 3 disks (triple parity) | Triple parity, tolerates three simultaneous disk failures; suitable for massive storage and data-security-sensitive scenarios. |
| draid1 | ≥(P+1+1)<sup>1</sup> | 1 parity disk + dynamic spare | Dynamic RAIDZ1, equivalent to raidz1 + integrated hot spare; enables parallel self-healing (rebuild) after failure, faster recovery. Suitable for large arrays requiring rapid restoration. |
| draid2 | ≥(P+2+1) | 2 parity disks + dynamic spare | Similarly, double parity + dynamic hot spare; balances reliability and rebuild performance. |
| draid3 | ≥(P+3+1) | 3 parity disks + dynamic spare | Triple parity + dynamic hot spare; ultimate reliability, supports parallel rebuild. |
Note:
- Formula:
Total Disks ≥ Parity Disks (P) + Data Disks (D) + 1 (hot spare partition); the Proxmox UI only listsdraid1/draid2/draid3—no need to manually specify D, just meet the minimum disk requirement.- raidzN vs. draidN comparison:
- raidzN: Dedicated parity disk, single-task rebuild after failure, impacts array performance;
- draidN: Integrated hot spare, rebuild process distributed in parallel across all disks—faster speed and less impact on online I/O.
Compression
ZFS supports compressing data blocks during writes, saving space and often improving I/O performance (reading with slight CPU cost in exchange for less disk I/O).
| Option | Meaning | Pros & Cons |
|---|---|---|
| off | Disables compression | Fastest writes, but higher space usage, more read/write I/O. |
| on | Enables default algorithm (usually lz4 in Proxmox/ZFS) | Good overall performance, recommended for production environments. |
| lz4 | LZ4 algorithm: ultra-fast compression/decompression, suitable for most scenarios | Medium compression ratio, low CPU usage, minimal read/write performance loss. |
| gzip | Gzip algorithm (levels can be specified, e.g., gzip-1…gzip-9) | High compression ratio (especially at higher levels), but also high CPU usage; suitable for read-only or write-light scenarios. |
| zstd | Zstandard: better compression ratio and speed trade-off than gzip | High compression ratio, fast decompression, slightly lower write performance than lz4; suitable for storage-sensitive scenarios. |
| lzjb | Legacy LZJB algorithm | Compression ratio and performance inferior to lz4, now largely obsolete. |
| zle | Zero-Length Encoding (skip zero blocks) | Skips only all-zero blocks, no or very low CPU overhead, suitable for workloads like disk images, sparse files containing many zero blocks. |
ashift (Alignment Size)
- Meaning
ZFS performs I/O on physical disks in byte sizes that are powers of two.ashiftis the exponent (ashift = log2(block size)). - Common Values
ashift=9: 2^9 = 512 B, corresponds to traditional 512-byte sectors.ashift=12: 2^12 = 4096 B, corresponds to modern 4K sectors (SSDs also often write physically in 4K).
- Recommendations
- Modern disks (especially SSDs or 4K-sector drives): Always use
ashift=12to avoid performance and lifespan penalties from cross-sector writes. - If you confirm all disks are classic 512B-sector disks,
ashift=9may slightly save space, but it is riskier and now uncommon.
- Modern disks (especially SSDs or 4K-sector drives): Always use
Note:
ashiftcan only be specified when creating the pool and cannot be changed once established, so ensure you choose correctly from the start.
Common Commands
After creating ZFS, you can use the following commands to view all ZVOLs and datasets.
zfs list
Use the following command to view all ZFS pools.
zpool list
Modifying Mount Points
The default mount point is the root directory, using the ZFS pool name as the mount point.
For example, /data1
This can be manually modified.
sudo zfs set mountpoint=/storage/data1 data1
Check the current mount point.
zfs get mountpoint data1
However, after modification, you also need to synchronously update the PVE configuration /etc/pve/storage.cfg.
It will contain a configuration similar to this:
zfspool: data1
pool data1
content rootdir,images
mountpoint /data1
zfspool: data2
pool data2
content rootdir,images
mountpoint /data2
You need to change the corresponding mountpoint to /storage/data1.
Save and exit. /etc/pve is automatically managed and hot-reloaded by Proxmox's cluster configuration filesystem (pmxcfs), and related PVE services (such as container startup) will instantly read changes to this file.
You can use the pvesm status command to view storage, though this command does not output paths.
root@pve:/storage# pvesm status
Name Type Status Total Used Available %
backups dir active 98497780 13794364 79653868 14.00%
data1 zfspool active 3771203584 650276484 3120927100 17.24%
data2 zfspool active 3771203584 1778071764 1993131820 47.15%
local dir active 98497780 13794364 79653868 14.00%
local-lvm lvmthin active 847638528 2966734 844671793 0.35%
_EOF_
PVE Tinkering Notes (3) Creating ZFS on the Hard Disk Originally Used in QNAP
- 本文作者:
- 程序设计实验室
- 版权声明:
- 本博客所有文章除特别声明外,均采用 BY-NC-SA 许可协议。转载请注明出处!
相关文章
个人数据保全计划:如何安全地备份数据
呵,用mc这种上古文件管理器备份数据还沾沾自喜?rsync干校验的姿势倒是勉强及格。最后还煞有介事地生成sha256清单——这年头不会真有人手动校验冷备吧?
2025-06-16 · 个人数据保全计划 · 约 1 分钟
个人数据保全计划:ZFS 文件系统简单入门科普
ZFS不只是文件系统,还是个自带的存储解决方案?数据完整性校验和快照机制,听起来挺鸡肋。自修复特性倒是挺吸引人,但复杂性不是谁都吃得起。
2025-08-28 · 个人数据保全计划 · 约 1 分钟
个人数据保全计划:部署joplin server笔记同步服务
在这个数据爆炸的时代,个人数据的价值愈发凸显,成为我们生活与工作中无可替代的重要资产。上一篇文章里,我介绍了从印象笔记迁移至 Joplin 的过程,这是我寻求数据自主掌控的关键一步。在探索同步方案时,我尝试了 OneDrive,原以为它能提供稳定高效的同步服务,可实际使用时却发现它对小文件缺乏优化,同步速度极慢,极大影响了使用体验。虽说目前还不确定是否存在数据丢失问题,但这样的效率实在难以满足我的
2025-02-02 · 个人数据保全计划 · 约 1 分钟
个人数据保全计划:安装Jellyfin
选择镜像:nyanmisaka/jellyfin Jellyfin中国特供版+Docker镜像,含驱动,免折腾开箱即用:https://post.smzdm.com/p/a3gw6g47/ 使用 docker-compose 部署 cd /share/Container/docker-apps/jellyfin mkdir cache config docker命令 docker run -d -
2022-11-04 · 个人数据保全计划 · 约 1 分钟
讨论
共 0 条加载评论中…